WebRTC - What is the proper way to create RTC Data Channel? - javascript

I work on WebRTC JS app and stcuk at a point where I need to crete a data channel. I have this part of code which actually works but openRTCDataChannel method is being executed twice:
this.myRTCConnections[id][hash]=window.RTCPeerConnection?new RTCPeerConnection(this.RTCConfiguration,{optional:[]}):(window.mozRTCPeerConnection?new mozRTCPeerConnection(this.RTCConfiguration,{optional:[]}):new webkitRTCPeerConnection(this.RTCConfiguration,{optional:[]}));
this.myRTCConnections[id][hash].ondatachannel=function(event){This.openRTCDataChannel(event,id,hash)}//first calling of openRTCDataChannel method
this.openRTCDataChannel(false,id,hash)//second calling of openRTCDataChannel method
this.openRTCDataChannel=function(event,id,hash,onOffer,initiator){
var RTCDataChannelOptions={reliable:true},This=this
if(!this.myRTCDataChannels[id])this.myRTCDataChannels[id]={}
this.myRTCDataChannels[id][hash]=event&&event.channel?event.channel:this.myRTCConnections[id][hash].createDataChannel("myDataChannel",RTCDataChannelOptions)
this.myRTCDataChannels[id][hash].onerror=function(error){log(error)}
this.myRTCDataChannels[id][hash].onmessage=function(e){This.handleIncomingRTCMessage(e.data,id,hash)}
this.myRTCDataChannels[id][hash].onclose=function(e){This.onSignalingServerLeave(false,id,hash)}
this.myRTCDataChannels[id][hash].onopen=function(e){This.onRTCDataChannelOpen(id,hash,onOffer,initiator)}
}
If I comment first or second calling if openRTCDataChannel method some of my peers can exchange data between themselves and some can not.
So the problem is that if I want my code to work I need to execute openRTCDataChannel method twice in two different ways. What am I doing wrong and what is the best way to start data channel which would work in all browsers?
Any help appreciated!

Ok. SO it seems I have found out what is wrong here.
Peer that initiates the connection and sending an offer should create data channel this way:
this.openRTCDataChannel(false,id,hash)
And another peer which accepts the offer and sending an answer should use this:
this.myRTCConnections[id][hash].ondatachannel=function(event){This.openRTCDataChannel(event,id,hash)}
I checked this in Mozilla and Chrome and it worked for me. Correct me if I am wrong.

Related

Better alternative to pinging the database over and over?

I want to create a dashboard that automatically updates when new data is posted.
My first thought was to just make a javascript function and put a fetch statement in it and then loop the function every second or every couple of seconds...
Obviously, this is not a great solution. But I don't know what the better way is...
Some notes:
-PHP Server-Side Language
-Ran on Localhost so traffic is not going over the internet
Can anyone advise what I should be doing or if this is an acceptable approach?
Thanks in advance!
Server Side:
You can look for any onUpdate events if your database supports any such events
Or else just run a query in a timed interval to fetch new updates form the database (Connection to database is made just once and all subsequent requests go through the same connection. Hence this isn't a bad approach)
But when it comes to client side and receiving those updates, you can make it efficient in either of the two ways:
[Simple] Use Socket IO - Push an event with your new data and listen to them on the client side. (This way socket connection is made just once and all subsequent responses are received in the same connection)
Docs: https://socket.io/docs/v4/index.html
[Complex] Use HTTP stream
Example: https://gist.github.com/igrigorik/5736866

Getting CallSid from Twilio in ougoing calls using js

I would like to know if there is any way to retrieve CallSid using TwilioJS library from an outgoing call done from a Browser to a Phone. The think is that I'm not able to post anything from my client to my server since I don't have any id of the call.
I've tried to find out the parameters of the connection object:
var connection = Twilio.Device.connect()
But no CallSid appears there.
Does anyone know how can a get this parameter, or something that lets me to identify the ougoing call that I've just done from js library?
Thanks :D
As seen in https://www.twilio.com/docs/client/connection, connection should be a Twilio.Connection object which has a property named parameters with a CallSid attribute both for incoming and outgoing connections.
It is probably only available after the connection is made, so you should use an event handler for connect event:
Twilio.Device.connect(function(connection) {
var callSid = connection.parameters.CallSid;
});

Poco C++ websockets - how to use in non-blocking manner?

I am using the Poco C++ libraries to setup a websocket server, which clients can connect to and stream some data to their webinterface. So I have a loop which continuously sends data and I also want to listen if the clients closes the connection by using the receiveFrame() function, for the rest, the client is totally passive and doesn't send any data or whatsoever. The problem is that receiveFrame() blocks the connection, which is not what I want. I basically want to check if the client has not yet called the close() javascript function and stop streaming data if it has. I tried using
ws.setBlocking(false);
But now receiveFrame throws an exception every time it is called. I also tried removing receiveFrame entirely, which works if the connection is terminated by closing the browser but if the client calls the function close(), the server still tries to send data to the client. So how can I pull this off? Is there somehow a way to check if there are client frames to be received and if not to just continue?
You can repeatedly call Socket::select() (with timeout) in a separate thread; when you detect a readable socket, call receiveFrame(). In spite of the misleading name, Socket::select() call wraps epoll() or poll() on platforms where those are available.
You can also implement this in somewhat more complicated but perhaps a more elegant fashion with Poco::NotificationQueues, posting a notification every time when a socket is readable and reading data in the handler.
setBlocking() does not do what you would expect it to. Here's a little info on it:
http://www.scottklement.com/rpg/socktut/nonblocking.html
What you probably want to do is use setReceiveTimeout() on your socket to control how long it will wait for before giving you back control. Then test your response and loop everything if needed. The Poco docs have more info on how to use that part of the API. Just look up WebSockets.

How to subscribe via DDP connections to other Meteor servers on the server side?

I'd like to synchronize Data between two Meteor apps. Therefore I have published a collection with the data in question on both apps (which obviously run the same Meteor version 0.8.1.2 with the exact same packages).
When I run
var testConnection = DDP.connect('http://10.0.10.20:3003/');
var newCollection = new Meteor.Collection('remoteData', testConnection);
testConnection.subscribe('remoteData');
console.log('Data list starts here:');
newCollection.find().forEach(function(data){console.log(data)});
on any client I do get a list of all data like expected. Server side there is nothing so newCollection stays empty (also I know from debugging that the server does actually execute testConnection.subscribe('remoteData') and the other server executes everything within its corresponding publish function just like for clients).
I tried it this way as the poster here https://stackoverflow.com/a/18360441 mentioned something like this works on client and server. Looking in the docs for subscribe ( http://docs.meteor.com/#meteor_subscribe ) it says it only works on the client which would explain that nothing happens on my server but would be a bit strange as DDP.connect ( http://docs.meteor.com/#ddp_connect ) seems to be meant for client and server and supports subscribe.
So do I miss something here? And what would be the best way to get a subscribe like functionality between two servers if subscribe really does not work in this scenario?
I know I can work with custom Meteor.methods but this seems a bit like a crutch compared to how nice it would work with subscribe, so I would be very interested in any better solution...
Like user728291 pointed out the problem was that the server in this case isn't waiting for this.ready() in the publish function on the other side and therefore when newCollection.find() is called on the server newCollection still is empty (but will receive data shortly after). It seems that on the client newCollection.find() tries to wait for this.ready() of the servers publish function (also I'm absolutely not sure about this, maybe the reason it works on the client is a totally different one) and therefore on the client it isn't empty at that time.
Anyhow, you are on the safe side when you always trigger find() in the callback of subscribe which will interpret any function as onReady callback (http://docs.meteor.com/#meteor_subscribe).
So what guaranteed works on server and client is
var testConnection = DDP.connect('http://10.0.10.20:3003/');
var newCollection = new Meteor.Collection('remoteData', testConnection);
testConnection.subscribe('remoteData', function() {
console.log('Data list starts here:');
newCollection.find().forEach(function(data){console.log(data)});
});

Using strophe attach() instead of connect() doesn't work unless I trigger my connected callback twice

I'm using prosody XMPP server and trying out chapter 3 example from "Professional XMPP Programming with JavaScript and jQuery". It is basically ping - pong example and it works fine. Problem is when I try to modify this example to store jid, sid and rid inside cookie to use this data to call strophie attach() instead of connect() on page reload. My example works great if I'm doing two or more pings one by one, if i'm doing only one server doesn't return anything. Here's my code:
The whole Javascript code is here
Problem is when I do $(document).trigger('connected'); twice in on_connect function when status === Strophe.Status.ATTACHEDI get two pings sent and pong handler is trigerred twice. When I trigger ping only once, pong handler doesn't get called ever.
Thanks in advance.
Your rid number must plus one when you attach()
make this change in your code:
Hello.connection.attach(data.jid, data.sid, parsInt(data.rid,10)+1, Hello.on_connect);

Categories