WebRTC on shared hosting ( SSH ) without nodejs, preferrably in php - javascript

So ive been looking for a way to integrate webRTC into a site im making, but i want to do it on shared hosting. I came across this repo on GitHub by nielsbaloe and it has been a huge help in getting a basic connection.
This is the code i believe is responsible for adding the peer: ( index.html in the repo, line )
function icecandidate(localStream) {
pc = new RTCPeerConnection(configuration);
pc.onicecandidate = function (event) {
if (event.candidate) {
publish('client-candidate', event.candidate);
}
};
try {
pc.addStream(localStream);
}catch(e){
var tracks = localStream.getTracks();
for(var i=0;i<tracks.length;i++){
pc.addTrack(tracks[i], localStream);
}
}
pc.ontrack = function (e) {
document.getElementById('remoteVideo').style.display="block";
document.getElementById('localVideo').style.display="none";
remoteVideo.srcObject = e.streams[0];
};
}
Now the struggle im facing is adding room functionality, and maybe the ability to have more than two concurrent peers present at the same time. I did some experimenting, but in vain. I know that for room functionality id have to tinker around in the php, so at least id like to figure out how to make more than 1 peer possible.

As far as I know, there is no way to re-use the same RTCPeerConnection for multiple peers, so you'll have to do the same thing as 1-on-1 but between every single peerĀ in a group.
As far as signalling, it's pretty simple, goes kind of like this:
Client A -> [Offer] -> Server -> [Offer] -> Client B -> [Answer] -> Server -> [Answer] -> Client A
A nicer explanation at MDN
There isn't necessarily a need for NodeJS or WebSocket. The reason most people go for it it is because the last link in this chain (Server -> Client A) requires server-initiated connection. But that can be substituted with alternative techniques such as (long-)polling. Or, in case of PHP, you might use websocket implementations such as Bloatless or Aerys
To implement the room functionality, you'll have to implement the following:
Variant A (using polling):
An endpoint to throw offers at, e.g. POST /rooms/{id}
An endpoint to regularly check for new offers from, e.g. GET /rooms/{id}
Variant B (with websockets)
Create a broadcast rooms, for example, by dynamically creating HTTP endpoints and websocket server instances. Or by having a single websocket instance but sending whatever room you're intending to join right inside after establishing a connection. From there, it's only a matter of sending correct offers and answers to correct users.
In both cases, you might want to either create multiple offers in advance to pool from the server, or to dynamically create new ones, but, most importantly, make sure you're not connecting the same peers twice, otherwise you will end up with a loop. To prevent it, just provide each user with a randomly generated string to identify themself and send it among offers.
There are turnkey solutions available if you don't want to go this route, but be careful and check whether you can use your own TURN servers with them. A common trend I have noticed is that there are a lot of WebRTC solution providers out there that lure you with their simplicity but then lock you in with their own TURN servers for which you might have to pay a quite hefty bill later on.

Related

js-ipfs connect two browser peers

I have 2 devices (desktop PCs), each running a browser tab that instantiates an IPFS node using js-ipfs.
//file index.html, served over HTTPS
const node = IpfsCore.create(); //ipfs browser node
Both nodes have peers (calling node.swarm.addrs() returns about 50 peers). They do not list each other as peers.
I want to connect those two nodes to each other, so if I call node.add( ... ) on the first, I can then call node.cat( ... ) on the second, and acquire a file from the first. (Or so that browser 1's pubsub broadcasts always reach browser 2; browser 1 can read browser 2's wantlist etc.)
How do I connect these 2 browser tabs as peers?
The example at https://github.com/ipfs/js-ipfs/blob/master/packages/interface-ipfs-core/src/swarm/connect.js uses this command:
ipfsA.swarm.connect( ipfsBId.addresses[0] )
But in my case, both my browser-tabs have no addresses.
console.log( ( await node.id() ).addresses ); //[] empty array
I don't know how the browser tabs manage connecting to other peers without their own addresses, and I don't know how to make them connect to each other.
There is a 4-year-old question about browser peers here IPFS - pubsub connect to peers from browser, but its fairly unrelated and seems to rely on the the deprecated / out-of-date webrtc-star https://github.com/libp2p/js-libp2p-webrtc-star
I know if I were setting up a WebRTC connection I would use fetch() or XHR or a websocket to a public-facing server (with a DNS record or IP address) to exchange negotiation info while querying a list of iceServers (also with DNS records / IP addresses).
I don't want to rely on a list of servers I own or configure, and I don't want to burden any public example TURN servers or anything. js-libp2p might use multicastDNS? I don't think browser tabs can broadcast signals though (I could be wrong? Maybe fetch() can do that somehow with some sneaky url stuff?)
What do I do? How can these two browser-tab IPFS peers discover each other, specifically?
I suspect this has a very straight-forward answer, but I have been researching for days now and read hundreds of pages, and none of the documentation I have read anywhere is relevant. Wherever the answer is on this vast Internet, I have not been able to find it.

Socket in javascript

please what is different
var socket = new WebSocket('ws://localhost:8181');
var socket = new WebSocket('ws://localhost:8181/websession');
what is ( Websession )
websession is just the endpoint the websocket will connect to. It's just like normal HTTP servers or REST services: You can have multiple endpoints on one server, like:
ws://localhost:8181/customers
ws://localhost:8181/prices
ws://localhost:8181/items
... and so on. (This is just an example and does not necessarily make sense for a specific use case.) In old-style HTTP, you could image them as different directories on the same server, possibly offering very different contents.
In order to use the socket correctly, you have to know your desired endpoint and use it when creating the socket. So it depends on the server whether ws://localhost:8181 or ws://localhost:8181/websession is correct (or even both of them, depending on the purpose of the individual endpoint). It's generally a good practice to give the endpoint a meaningful name, so the first one would be discouraged.
As the application seems to be running on your localhost, you should take a look at the server running at port 8181 to find out the endpoints offered. And you could possibly get used to websockets, here is one of many possible starting points.

Correct way to handle Websocket

I've a client to server Websocket connection which should be there for 40 seconds or so. Ideally it should be forever open.
The client continually sends data to server and vice-versa.
Right now I'm using this sequence:
var socket;
function senddata(data)
{
if (!socket)
{
socket = new WebSocket(url);
socket.onopen = function (evt) {
socket.send(data);
socket.onmessage = function (evt) {
var obj = JSON.parse(evt.data);
port.postMessage(obj);
}
socket.oneerror = function (evt) {
socket.close();
socket = null;
}
socket.onclose = function(evt){
socket = null;
}
}
}
else
{
socket.send(data);
}
}
Clearly as per current logic, in case of error, the current request data may not be sent at all.
To be frank it sometimes gives error that websocket is still in connecting state. This connection breaks often due to networking issues. In short it does not work perfectly well.
I've read a better design : How to wait for a WebSocket's readyState to change but does not cover all cases I need to handle.
Also I've Googled about this but could not get the correct procedure for this.
So what is the right way to send regular data through Websockets which handles well these issues like connection break etc?
An event you don't seem to cover is onclose. Which should work really well, since it's called whenever the connection terminates. This is more reliable than onerror, because not all connection disruptions result in an error.
I personally use Socket.IO, it enables real-time bidirectional event-based communication between client and server.
It is event driven. Events such as
on connection :: socket.on('conection',callback);
and
on disconnect :: socket.on('disconnect',callback);
are built in with socket.io so it can help you with your connection concerns. Pretty much very easy to use, check out their site if you are interested.
I use two-layer scheme on client: abstract-wrapper + websocket-client:
The responsibilities of the websocket-client are interacting with a server, recovering the connection and providing interfaces (event-emitter and some methods) to abstract-wrapper.
The abstract-wrapper is a high-level layer, which interacts with websocket-client, subscribes to its events and aggregating data, when the connection is temporary failed. The abstract-wrapper can provide to application layer any interface such as Promise, EventEmitter and so on.
On application layer, I just work with abstract-wrapper and don't worry about connection or data losing. Undoubtedly, it's a good idea to have here information about the status of connection and data sending confirmation, because it's useful.
If it is necessary, I can provide some code for example
This apparently is a server issue not a problem in the client.
I don't know how the server looks like here. But this was a huge problem for me in the past when I was working on a websocket based project. The connection would continuously break.
So I created a websocket server in java, and that resolved my problem.
websockets depend on lots of settings, like if you're using servlets then servlet container's settings matter, if you're using some php etc, apache and php settings matter, for example if you create a websocket server in php and php has default time-out of 30 seconds, it will break after 30 seconds. If keep-alive is not set, the connection wont stay alive etc.
What you can do as quick solution is
keep sending pings to a server after a certain amount of time (like 2 or 3 seconds, so that if a websocket is disconnected it is known to the client so it could invoke onclose or ondisconnect, I hope you know that there is no way to find if a connection is broken other than failing to send something.
check server's keep-alive header
If you have access to server, then it's timeouts etc.
I think that would help

Publish data from browser app without writing my own server

I need users to be able to post data from a single page browser application (SPA) to me, but I can't put server-side code on the host.
Is there a web service that I can use for this? I looked at Amazon SQS (simple queue service) but I can't call their REST APIs from within the browser due to cross origin policy.
I favour ease of development over robustness right now, so even just receiving an email would be fine. I'm not sure that the site is even going to catch on. If it does, then I'll develop a server-side component and move hosts.
Not only there are Web Services, but nowadays there are robust systems that provide a way to server-side some logic on your applications. They are called BaaS or Backend as a Service providers, usually to provide some backbone to your front end applications.
Although they have multiple uses, I'm going to list the most common in my opinion:
For mobile applications - Instead of having to learn an API for each device you code to, you can use an standard platform to store logic and data for your application.
For prototyping - If you want to create a slick application, but you don't want to code all the backend logic for the data -less dealing with all the operations and system administration that represents-, through a BaaS provider you only need good Front End skills to code the simplest CRUD applications you can imagine. Some BaaS even allow you to bind some Reduce algorithms to calls your perform to their API.
For web applications - When PaaS (Platform as a Service) came to town to ease the job for Backend End developers in order to avoid the hassle of System Administration and Operations, it was just logic that the same was going to happen to the Backend. There are many clones that showcase the real power of this strategy.
All of this is amazing, but I have yet to mention any of them. I'm going to list the ones that I know the most and have actually used in projects. There are probably many, but as far as I know, this one have satisfied most of my news, whether it's any of the previously ones mentioned.
Parse.com
Parse's most outstanding features target mobile devices; however, nowadays Parse contains an incredible amount of API's that allows you to use it as full feature backend service for Javascript, Android and even Windows 8 applications (Windows 8 SDK was introduced a few months ago this year).
How does a Parse code looks in Javascript?
Parse works through classes and objects (ain't that beautiful?), so you first create a specific class (can be done through Javascript, REST or even the Data Browser manager) and then you add objects to specific classes.
First, add up Parse as a script tag in javascript:
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-1.1.15.min.js"></script>
Then, through a given Application ID and a Javascript Key, initialize Parse.
Parse.initialize("APPLICATION_ID", "JAVASCRIPT_KEY");
From there, it's all object manipulation
var Person = Parse.Object.extend("Person"); //Person is a class *cof* uppercase *cof*
var personObject = new Person();
personObject.save({name: "John"}, {
success: function(object) {
console.log("The object with the data "+ JSON.stringify(object) + " was saved successfully.");
},
error: function(model, error) {
console.log("There was an error! The following model and error object were provided by the Server");
console.log(model);
console.log(error);
}
});
What about authentication and security?
Parse has a User based authentication system, which pretty much allows you to store a base of users that can manipulate the data. If map the data with User information, you can ensure that only a given user can manipulate specific data. Plus, in the settings of your Parse application, you can specify that no clients are allowed to create classes, to ensure innecesary calls are performed.
Did you REALLY used in a web application?
Yes, it was my tool of choice for a medium fidelity prototype.
Firebase.com
Firebase's main feature is the ability to provide Real Time to your application without all the hassle. You don't need a MeteorJS server in order to bring Push Notifications to your software. If you know Javascript, you are half way through to bring Real Time magic to your users.
How does a Firebase looks in Javascript?
Firebase works in a REST fashion, and I think they do an amazing job structuring the Glory of REST. As a good example, look at the following Resource structure in Firebase:
https://SampleChat.firebaseIO-demo.com/users/fred/name/first
You don't need to be a rocket scientist to know that you are retrieve the first name of the user "Fred", giving there's at least one -usually there should be a UUID instead of a name, but hey, it's an example, give me a break-.
In order to start using Firebase, as with Parse, add up their CDN Javascript
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase.js'></script>
Now, create a reference object that will allow you to consume the Firebase API
var myRootRef = new Firebase('https://myprojectname.firebaseIO-demo.com/');
From there, you can create a bunch of neat applications.
var USERS_LOCATION = 'https://SampleChat.firebaseIO-demo.com/users';
var userId = "Fred"; // Username
var usersRef = new Firebase(USERS_LOCATION);
usersRef.child(userId).once('value', function(snapshot) {
var exists = (snapshot.val() !== null);
if (exists) {
console.log("Username "+userId+" is part of our database");
} else {
console.log("We have no register of the username "+userId);
}
});
What about authentication and security?
You are in luck! Firebase released their Security API about two weeks ago! I have yet to explore it, but I'm sure it fills most of the gaps that allowed random people to use your reference to their own purpose.
Did you REALLY used in a web application?
Eeehm... ok, no. I used it in a Chrome Extension! It's still in process but it's going to be a Real Time chat inside a Chrome Extension. Ain't that cool? Fine. I find it cool. Anyway, you can browse more awesome examples for Firebase in their examples page.
What's the magic of these services? If you read your Dependency Injection and Mock Object Testing, at some point you can completely replace all of those services for your own through a REST Web Service provider.
Since these services were created to be used inside any application, they are CORS ready. As stated before, I have successfully used both of them from multiple domains without any issue (I'm even trying to use Firebase in a Chrome Extension, and I'm sure I will succeed soon).
Both Parse and Firebase have Data Browser managers, which means that you can see the data you are manipulating through a simple web browser. As a final disclaimer, I have no relationship with any of those services other than the face that James Taplin (Firebase Co-founder) was amazing enough to lend me some Beta access to Firebase.
You actually CAN use SQS from the browser, even without CORS, as long as you only need the browser to send messages, not receive them. Warning: this is a kludge that would make my CS professors cry.
When you perform a GET request via javascript, the browser will always perform the request, however, you'll only get access to the response if it was from the same origin (protocol, host, port). This is your ticket to ride, since messages can be posted to an SQS queue with just a GET, and who really cares about the response anyways?
Assuming you're using jquery, your queue is https://sqs.us-east-1.amazonaws.com/71717171/myqueue, and allows anyone to post a message, the following will post a message with the body "HITHERE" to the queue:
$.ajax({
url: 'https://sqs.us-east-1.amazonaws.com/71717171/myqueue' +
'?Action=SendMessage' +
'&Version=2012-11-05' +
'&MessageBody=HITHERE'
})
The'll be an error in the console saying that the request failed, but the message will show up in the queue anyways.
Have you considered JSONP? That is one way of calling cross-domain scripts from javascript without running into the same origin policy. You're going to have to set up some script somewhere to send you the data, though. Javascript just isn't up to the task.
Depending in what kind of data you want to send, and what you're going to do with it, one way of solving it would be to post the data to a Google Spreadsheet using Ajax. It's a bit tricky to accomplish though.Here is another stackoverflow question about it.
If presentation isn't that important you can just have an embedded Google Spreadsheet Form.
What about mailto:youremail#goeshere.com ? ihihi
Meantime, you can turn on some free hostings like Altervista or Heroku or somenthing else like them .. so you can connect to their server , if i remember these free services allows servers p2p, so you can create a sort of personal web services and push ajax requests as well, obviously their servers are slow for free accounts, but i think it's enought if you do not have so much users traffic, else you should turn on some better VPS or Hosting or Cloud solution.
Maybe CouchDB can provide what you're after. IrisCouch provides free CouchDB instances. Lock it down so that users can't view documents and have a sensible validation function and you've got yourself an easy RESTful place to stick your data in.

Private messaging through node.js

I'm making a multiplayer (2 player) browser game in JavaScript. Every move a player makes will be sent to a server and validated before being transmitted to the opponent. Since WebSockets isn't ready for prime time yet, I'm looking at long polling as a method of transmitting the data and node.js looks quite interesting! I've gone through some example code (chat examples, standard long polling examples and suchlike) but all the examples I've seen seem to broadcast everything to every client, something I'm hoping to avoid. For general server messages this is fine but I want two players to be able to square off in a lobby or so and go into "private messaging" mode.
So I'm wondering if there's a way to implement private messaging between two clients using nodejs as a validating bridge? Something like this:
ClientA->nodejs: REQUEST
nodejs: VALIDATE REQUEST
nodejs->ClientA: VALID
nodejs->ClientB: VALID REQUEST FROM ClientA
You need some way to keep track of which clients are in a lobby together. You can do this with a simple global array like so process.lobby[1] = Array(ClientASocket, ClientBSocket) or something similar (possibly with some additional data, like nicknames and such), where the ClientXSocket is the socket object of each client that connects.
Now you can hook the lobby id (1 in this case) onto each client's socket object. A sort of session variable (without the hassle of session ids) if you will.
// i just made a hashtable to put all the data in,
// so that we don't clutter up the socket object too much.
socket.sessionData['lobby'] = 1;
What this allows you to do also, is add an event hook in the socket object, so that when the client disconnects, the socket can remove itself from the lobby array immediately, and message the remaining clients that this client has disconnected.
// see link in paragraph above for removeByValue
socket.on('close', function(err) {
process.lobby[socket.sessionData['lobby']].removeByValue(socket);
// then notify lobby that this client has disconnected.
});
I've used socket in place of the net.Stream or request.connection or whatever the thing is.
Remember in HTTP if you don't have keep-alive connections, this will make the TCP connection close, and so of course make the client unable to remain within a lobby. If you're using a plain TCP connection without HTTP on top (say within a Flash application or WebSockets), then you should be able to keep it open without having to worry about keep-alive. There are other ways to solve this problem than what I've shown here, but I hope I got you started at least. The key is keeping a persistent object for each client.
Disclaimer: I'm not a Node.js expert (I haven't even gotten around to installing it yet) but I have been reading up on it and I'm very familiar with browser js, so I'm hoping this is helpful somehow.

Categories

Resources