why doesn't "onicecandidate" work?

14,915

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).

Share:
14,915
Fab
Author by

Fab

Updated on June 25, 2022

Comments

  • Fab
    Fab almost 2 years

    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 :)

  • Fab
    Fab about 11 years
    Thanks for your explanation! It's starting to make more sense now.
  • kennysong
    kennysong almost 9 years
    This still does not call onicecandidate.
  • zim32
    zim32 over 8 years
    For me too. Maybe because of both channels are on the same side?
  • Qix - MONICA WAS MISTREATED
    Qix - MONICA WAS MISTREATED almost 7 years
    See this answer to get ice candidates working. The methodology in this answer is correct, but the createOffer() arguments have changed (several times now).