Why is my Ice Candidate request triggered 6 times instead of 1?

I am writing my first peer-to-peer application to connect via WebRTC, and my code, to request an ice peer candidate that I send through socket.io, runs 6 times, not once.

This is really confusing, because if I mistakenly designed a large query loop, I would expect endless recursions, not just 6 (8 onicecandidate events). So can someone tell me why the following code created 6 recursions?

Here, the message handler, it simply sends a socket.io message driven by the syntax: Muveoo.Messenger.input('ice candidate request', data);

 'ice candidate request' : function(data) { console.log('Debug 10: Requesting Ice Candidate'); socket.emit('ice candidate request', data); }, 

And here is the code that processes the Ice Candidate request, do not confuse the if logic at the top, the UID is just a unique identifier assigned to each client to decide who should make the proposal initially.

 if (Muveoo.RTC.connectedPeers[id].dataChannels[name].UID < Muveoo.RTC.connectedPeers[id].dataChannels[name].peerUID) { Muveoo.RTC.connectedPeers[id].dataChannels[name].offerConnection(function() { console.log('[Debug A]: Offering Connection'); Muveoo.RTC.connectedPeers[id].dataChannels[name].pc.onicecandidate = function(evt) { console.log('[Debug A]: onicecandidate Event Triggered.'); if (evt.candidate) { console.log('[Debug A]: Sending Ice Candidate Request.'); Muveoo.Messenger.input('ice candidate request', { target : id, candidate : evt.candidate, channel : name }); } }; Muveoo.RTC.connectedPeers[id].dataChannels[name].pc.ondatachannel = function(evt) { console.log('got data channel'); Muveoo.RTC.connectedPeers[id].dataChannels[name] = evt.channel; Muveoo.RTC.connectedPeers[id].dataChannels[name].channel.onmessage = function(evt1) { handleMessage(evt1.data); }; Muveoo.RTC.connectedPeers[id].dataChannels[name].channel.message = function(msg) { Muveoo.RTC.connectedPeers[id].dataChannels[name].channel.send(JSON.stringify(msg)); }; }; socket.on('session description', function(data) { console.log('Debug 12: Session Description Received'); Muveoo.RTC.connectedPeers[data.target].dataChannels[data.channel].desc = new Muveoo.RTC.connectedPeers[data.target].dataChannels[data.channel].sessionDescription(msg.desc); Muveoo.RTC.connectedPeers[data.target].dataChannels[data.channel].pc.setRemoteDescription(Muveoo.RTC.connectedPeers[data.target].dataChannels[data.name].desc); if (Muveoo.RTC.connectedPeers[data.target].dataChannels[data.channel].UID > Muveoo.RTC.connectedPeers[data.target].dataChannels[data.channel].peerUID) { /*They sent the sessionDescription first, so need an answer*/ Muveoo.RTC.connectedPeers[data.target].dataChannels[data.channel].pc.createAnswer(function(answer) { /*The answer is this side local description*/ Muveoo.RTC.connectedPeers[data.target].dataChannels[data.channel].pc.setLocalDescription(answer); var data = { target : data.target, description : answer, channel : data.channel }; socket.emit('session description', data); }); } }); }); } 

And here are the resulting logs to show what is happening:

 [Debug A]: Offering Connection rtc.js:94 [Debug A]: onicecandidate Event Triggered. rtc.js:101 [Debug A]: Sending Ice Candidate Request. messenger.js:91 Debug 10: Requesting Ice Candidate rtc.js:94 [Debug A]: onicecandidate Event Triggered. rtc.js:101 [Debug A]: Sending Ice Candidate Request. messenger.js:91 Debug 10: Requesting Ice Candidate rtc.js:94 [Debug A]: onicecandidate Event Triggered. rtc.js:101 [Debug A]: Sending Ice Candidate Request. messenger.js:91 Debug 10: Requesting Ice Candidate rtc.js:94 [Debug A]: onicecandidate Event Triggered. rtc.js:101 [Debug A]: Sending Ice Candidate Request. messenger.js:91 Debug 10: Requesting Ice Candidate rtc.js:94 [Debug A]: onicecandidate Event Triggered. rtc.js:101 [Debug A]: Sending Ice Candidate Request. messenger.js:91 Debug 10: Requesting Ice Candidate rtc.js:94 [Debug A]: onicecandidate Event Triggered. rtc.js:94 [Debug A]: onicecandidate Event Triggered. rtc.js:101 [Debug A]: Sending Ice Candidate Request. messenger.js:91 Debug 10: Requesting Ice Candidate rtc.js:94 [Debug A]: onicecandidate Event Triggered. 

Why does my Ice Candidate request fire 6 times instead of 1?

+6
source share
1 answer

They are not requests. You are responsible for sending all ICE candidates that WebRTC generates to other partners through your signaling selection.

This project is called Trickle ICE and speeds up negotiations, without waiting for all candidates to be found in advance and implanted in a proposal / response, which may take a few seconds, so please send these messages as soon as possible (you should have already sent a proposal / response already by the time this fire is local, i.e. after setLocalDescription successful callback).

Each candidate is an IP + port to which your local client can be reached.

If you send only video (without sound) on the local LAN without the Internet (or you do not specify any STUN or TURN server), you will see only two host candidates, one for each direction. For instance.

 candidate:0 1 UDP 2133252543 192.168.1.5 58078 typ host candidate:0 2 UDP 2133252542 192.168.1.5 51446 typ host 

If you add a STUN server, you will additionally see candidates for server reflection, that is, how you will reach outside your firewall.

 candidate:1 1 UDP 1686032863 69.102.28.57 60453 typ srflx candidate:1 2 UDP 1686032862 69.102.28.57 62432 typ srflx 

Finally, if you add a TURN server, you will also see relay candidates who will be on the TURN server, which will transfer your data in a pinch (if there is no direct connection between peers):

 candidate:2 1 UDP 1153102742 12.202.18.33 71321 typ relay candidate:2 2 UDP 1153102741 12.202.18.33 71432 typ relay 

Add audio to this, and the number of candidates will double.

Here's a fiddle to experiment with.

0
source

All Articles