Search code examples
webrtcp2pnat-traversalrtcpeerconnection

Should empty string icecandidate be added by addicecandidate?


My question is about webrtc negotiation.

There is a contradiction in many online tutorials and what is described in MDN.

In MDN, it says link

At the end of each generation of candidates, an end-of-candidates notification is sent in the form of an RTCIceCandidate whose candidate property is an empty string. This candidate should still be added to the connection using addIceCandidate() method, as usual, in order to deliver that notification to the remote peer.

When there are no more candidates at all to be expected during the current negotiation exchange, an end-of-candidates notification is sent by delivering a RTCIceCandidate whose candidate property is null. This message does not need to be sent to the remote peer. It's a legacy notification of a state which can be detected instead by watching for the iceGatheringState to change to complete, by watching for the icegatheringstatechange event.

However, in the tutorial here, they introduce the following code

function handleICECandidateEvent(event) {
  if (event.candidate) {
    sendToServer({
      type: "new-ice-candidate",
      target: targetUsername,
      candidate: event.candidate
    });
  }
}

If candidate is an empty string, it will be evaluated falsy and not be sent via sendToServer.

More interestingly, even in a same article here

They have following sample code

rtcPeerConnection.onicecandidate = (event) => {
  if (event.candidate) {
    sendCandidateToRemotePeer(event.candidate)
  }
}

But right below this snippet, they say

When an ICE negotiation session runs out of candidates to propose for a given RTCIceTransport, it has completed gathering for a generation of candidates. That this has occurred is indicated by an icecandidate event whose candidate string is empty ("").

You should deliver this to the remote peer just like any standard candidate, as described under Sharing a new candidate above. This ensures that the remote peer is given the end-of-candidates notification as well.

Actually, I read many online tutorials but I have never seen anywhere where they handle the empty string candidate.


Solution

  • The old spec did not require sending an empty candidate, but the new spec require send and addIceCandidate() an empty candidate. Since Chrome is still an old specification, an empty candidate will cause an error when addedIceCandidate(), so I will not send it.