RTCPeerConnection: icecandidate 事件
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.
当 RTCPeerConnection
通过 RTCPeerConnection.setLocalDescription()
方法更改本地描述之后,该 RTCPeerConnection
会抛出 icecandidate
事件。该事件的监听器需要将更改后的描述信息传送给远端 RTCPeerConnection
,以更新远端的备选源。
使用指南
icecandidate
的类型为 RTCPeerIceCandidateEvent
, 在以下三种情况下会触发该事件:
分享新的候选
触发 icecandidate
事件的首要原因:当获得新的源之后,需要将该源的信息发送给远端信号服务器,并分发至其他端的 RTCPeerConnection
。其他 RTCPeerConnection
通过 addIceCandidate()
方法将新 candidate
中携带的信息,将新的源描述信息添加进它的备选池中;
rtcPeerConnection.onicecandidate = (event) => {
if (event.candidate) {
sendCandidateToRemotePeer(event.candidate);
} else {
/* 在此次协商中,没有更多的候选了 */
}
};
远程的节点在接受到候选后,将通过调用 addIceCandidate()
的方式将候选加入候选池中,并传入通过信令服务器得到的 candidate
字符串(作为参数)。
代表最后一轮候选结束
当一个 ICE 协商会话没有候选来提供给某个给定的 RTCIceTransport,就完成了一轮候选的收集。一个带有空字串("")的 icecandidate 事件出现,表明了这种情况。
你应当像对待任何普通候选一般向远程节点传递这个候选,正如在上述“共享一个新的候选”里所描述的。这就确保了远程节点也能获得候选终结的通知。正如你在上一个小节的代码里所见,每个候选都被发送到别的节点,包括任何可能含有空候选字串的。只有那些事件的 candidate 属性为 null 的不通过信令连接传递。
候选终结指示在 Trickle ICE draft 规范的 9.3 章有描述(注意,章节号码会根据标准的反复修正而发生改变)
代表 ICE 收集完成
一旦所有的 ICE 传输完成收集候选并且 RTCPeerConnection
对象的 iceGatheringState
的值变化成 complete
,一个 icecandidate
事件携带着值为 null
的 complete
属性的被发送。
这个信号的存在是为了向后兼容的目的,并且不需要向远程节点分发(这也就是为什么上面的代码片段检查了 event.candidate 是否为 null,优先于沿着候选发送)
如果你需要执行任何特别的动作,当没有更多的期待的候选,你最好通过观察 icegatheringstatechange
事件来观察 ICE 收集状态。
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;
}
});
如你在这个例子中看到的,icegatheringstatechange 事件让你知道 RTCPeerConnection 属性 iceGatheringState 被更新的时机。如果那个值现在是 complete,你就知道 ICE 收集刚刚结束。
对表明一个 ICE 会话已经结束而言,相比观察一个单独的 ICE 消息,这是更为可靠的方法。
示例
这个例子建立一个简单的 icecandidate 事件处理器,通过信令服务器使用一个 sendMessenge() 来建立和发送一个回复给远程节点。
首先,一个使用 addEventListener() 的例子:
pc.addEventListener(
"icecandidate",
(ev) => {
if (ev.candidate) {
sendMessage({ type: "new-ice-candidate", candidate: event.candidate });
}
},
false,
);
你也可以直接设定 onicecandidate
事件处理器的属性:
pc.onicecandidate = (ev) => {
if (ev.candidate) {
sendMessage({ type: "new-ice-candidate", candidate: event.candidate });
}
};
概述
属性
方法
方法继承自 RTCPeerConnectionIceEvent
.
相关事件
- 无
规范
Specification |
---|
WebRTC: Real-Time Communication in Browsers # dom-rtcpeerconnection-onicecandidate |
浏览器兼容性
BCD tables only load in the browser