Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why doesn't "onicecandidate" work?

I'm having trouble understanding webRTC with it's PeerConnection and 'onicecandidate' event.

As far as I understand it you must initiate a peerconnection using a STUN (or TURN) server, because it will send you back your ICE candidate for communication with another peer.

I've seen examples leaving the server parameter of the PeerConnection object out, which I don't understand as well, but let's just say it does need the server parameter.

So, when I write down the following code:

    var pc, ice = { "iceServers": [{ "url": "stun:stun.l.google.com:19302" }] };
if(typeof mozRTCPeerConnection === 'function') {

    pc = new mozRTCPeerConnection(ice);
}
else {
    console.log('google');
    pc = new webkitRTCPeerConnection(ice);
}


pc.onicecandidate  = function(event) { 
    console.log(event);
}

I expect that the 'onicecandidate' event will fire, but it doesn't work. I tried other public STUN servers as well, but nothing happens. So I assume there is probably something wrong with my comprehension :)

like image 585
Fab Avatar asked Mar 18 '13 18:03

Fab


1 Answers

The PeerConnection won't start gathering candidates until you call setLocalDescription(); the information supplied to setLocalDescription tells PeerConnection how many candidates need to be gathered. (This behavior for setLocalDescription is indicated in its definition at https://datatracker.ietf.org/doc/html/draft-ietf-rtcweb-jsep-03#section-4.2.4)

Here's what a complete flow looks like for establishing a connection between two PeerConnections in the same browser window (adding of MediaStreams omitted to focus on the signaling):

var pc1, pc2, offer, answer;

pc1 = new webkitRTCPeerConnection(options);
pc2 = new webkitRTCPeerConnection(options);

pc1.onicecandidate = function(candidate) {
  pc2.addIceCandidate(candidate);
};

pc2.onicecandidate = function(candidate) {
  pc1.addIceCandidate(candidate);
};

pc1.createOffer(onOfferCreated, onError);

function onError(err) {
  window.alert(err.message);
}

function onOfferCreated(description) {
  offer = description;
  pc1.setLocalDescription(offer, onPc1LocalDescriptionSet, onError);
}

function onPc1LocalDescriptionSet() {
  // after this function returns, pc1 will start firing icecandidate events
  pc2.setRemoteDescription(offer, onPc2RemoteDescriptionSet, onError);
}

function onPc2RemoteDescriptionSet() {
  pc2.createAnswer(onAnswerCreated, onError);
}

function onAnswerCreated(description) {
  answer = description;
  pc2.setLocalDescription(answer, onPc2LocalDescriptionSet, onError);
}

function onPc2LocalDescriptionSet() {
  // after this function returns, you'll start getting icecandidate events on pc2
  pc1.setRemoteDescription(answer, onPc1RemoteDescriptionSet, onError);
}

function onPc1RemoteDescriptionSet() {
  window.alert('Yay, we finished signaling offers and answers');
}

Since you included a mozPeerConnection in your question, I'll note that Firefox does not currently generate 'trickle candidates'. This means that it will include its candidate addresses as 'c' lines in the offer/answer, and the onicecandidate callback will never be called.

The downside to this approach is that Firefox must wait for all of its candidates to be gathered before creating its offer/answer (a process which can involve contacting STUN and TURN servers and waiting for either the responses or for the requests timeout).

like image 128
bstrong Avatar answered Nov 19 '22 16:11

bstrong