RTCPeerConnection: icecandidate event
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2017.
Anicecandidate
event is sent to anRTCPeerConnection
when:
- An
RTCIceCandidate
has been identified and added to the local peer by a call toRTCPeerConnection.setLocalDescription()
, - Every
RTCIceCandidate
correlated with a particular username fragment and password combination (ageneration) has been so identified and added, and - All ICE gathering on all transports is complete.
In the first two cases, the event handler should transmit the candidate to the remote peer over the signaling channel so the remote peer can add it to its set of remote candidates.
This event is not cancelable and does not bubble.
Syntax
Use the event name in methods likeaddEventListener()
, or set an event handler property.
addEventListener("icecandidate", (event) => { })onicecandidate = (event) => { }
Event type
AnRTCPeerConnectionIceEvent
. Inherits fromEvent
.
Event properties
ARTCPeerConnectionIceEvent
being anEvent
, this event also implements the following property.
RTCPeerConnectionIceEvent.candidate
Read onlyIndicates the
RTCIceCandidate
containing the candidate associated with the event.This will be the empty string if the event indicates that there are no further candidates to come in thisgeneration, ornull
if all ICE gathering on all transports is complete.
Description
There are three reasons why theicecandidate
event is fired on anRTCPeerConnection
.
Sharing a new candidate
The majority oficecandidate
events are fired to indicate that a new candidate has been gathered. This candidate needs to be delivered to the remote peer over the signaling channel your code manages.
rtcPeerConnection.onicecandidate = (event) => { if (event.candidate !== null) { sendCandidateToRemotePeer(event.candidate); } else { /* there are no more candidates coming during this negotiation */ }};
The remote peer, upon receiving the candidate, will add the candidate to its candidate pool by callingaddIceCandidate()
, passing in thecandidate
string you have passed along using the signaling server.
Indicating the end of a generation of candidates
When an ICE negotiation session runs out of candidates to propose for a givenRTCIceTransport
, it has completed gathering for ageneration of candidates. That this has occurred is indicated by anicecandidate
event whosecandidate
string is empty (""
).
You should deliver this to the remote peer just like any standard candidate, as described underSharing a new candidate above. This ensures that the remote peer is given the end-of-candidates notification as well. As you see in the code in the previous section, every candidate is sent to the other peer, including any that might have an empty candidate string. Only candidates for which the event'scandidate
property isnull
are not forwarded across the signaling connection.
The end-of-candidates indication is described insection 9.3 of the Trickle ICE draft specification (note that the section number is subject to change as the specification goes through repeated drafts).
Indicating that ICE gathering is complete
Once all ICE transports have finished gathering candidates and the value of theRTCPeerConnection
object'siceGatheringState
has made the transition tocomplete
, anicecandidate
event is sent with the value ofcandidate
set tonull
.
This signal exists for backward compatibility purposes and doesnot need to be delivered onward to the remote peer (which is why the code snippet above checks to see ifevent.candidate
isnull
prior to sending the candidate along).
If you need to perform any special actions when there are no further candidates expected, you're much better off watching the ICE gathering state by watching foricegatheringstatechange
events:
pc.addEventListener("icegatheringstatechange", (ev) => { switch (pc.iceGatheringState) { case "new": /* gathering is either just starting or has been reset */ break; case "gathering": /* gathering has begun or is ongoing */ break; case "complete": /* gathering has ended */ break; }});
As you can see in this example, theicegatheringstatechange
event lets you know when the value of theRTCPeerConnection
propertyiceGatheringState
has been updated. If that value is nowcomplete
, you know that ICE gathering has just ended.
This is a more reliable approach than looking at the individual ICE messages for one indicating that the ICE session is finished.
Examples
This example creates a simple handler for theicecandidate
event that uses a function calledsendMessage()
to create and send a reply to the remote peer through the signaling server.
First, an example usingaddEventListener()
:
pc.addEventListener( "icecandidate", (ev) => { if (ev.candidate !== null) { sendMessage({ type: "new-ice-candidate", candidate: ev.candidate, }); } }, false,);
You can also set theonicecandidate
event handler property directly:
pc.onicecandidate = (ev) => { if (ev.candidate !== null) { sendMessage({ type: "new-ice-candidate", candidate: ev.candidate, }); }};
Specifications
Specification |
---|
WebRTC: Real-Time Communication in Browsers # dom-rtcpeerconnection-onicecandidate |