ICE 候选人交换

正如我们已经预料到的,信令服务器的主要任务之一是使发起方和连接方之间的网络可达性信息能够交换,从而可以在两者之间建立媒体包流。 交互式连接建立(ICE)RFC5245 技术允许对等方发现有关彼此拓扑的足够信息,从而有可能在彼此之间找到一条或多条通信路径。

此类信息由与每个 RTCPeerConnection 对象关联的 ICE 代理在本地收集。 ICE 代理负责:

  • 收集本地IP,端口元组候选
  • 在同级之间执行连接检查
  • 发送连接保持活动

设置会话描述(本地或远程)后,本地 ICE 代理会自动开始发现本地对等方所有可能候选者的过程:

  1. ICE 代理向操作系统查询本地 IP 地址。
  2. 如果已配置,它将查询外部 STUN 服务器以检索对等方的公共 IP 地址和端口元组。
  3. 如果已配置,则代理还将 TURN 服务器用作最后的手段。 如果对等连接检查失败,则媒体流将通过 TURN 服务器进行中继。

每当发现新的候选对象(即IP,port tuple)时,ICE 代理就会自动将其注册到 RTCPeerConnection 对象,并通过回调函数(onIceCandidate)通知应用程序。 该应用程序可以决定在发现每个候选者之后(Trickle ICE)尽快将其转移到远程方,或者决定等待 ICE 收集阶段完成,然后立即发送所有候选者。

与该特定阶段关联的事件顺序如 图5-13 所示。

图5-13

图5-13 服务器引导的 ICE 候选人交换

该图显示,只要浏览器引发 IceCandidate 事件(因为已经收集了一个新的 ICE 候选对象),就会激活 handleIceCandidate() 处理程序。 此处理程序将检索到的候选者包装在专用候选者消息中,该消息将通过服务器发送给远程方:

  1. function handleIceCandidate(event) {
  2. console.log('handleIceCandidate event: ', event);
  3. if (event.candidate) {
  4. sendMessage({type: 'candidate',label: event.candidate.sdpMLineIndex,id: event.candidate.sdpMid,candidate: event.candidate.candidate});
  5. } else {
  6. console.log('End of candidates.');
  7. }
  8. }

像往常一样,服务器只是充当两个协商方之间的中介者,如 图5-14 中的控制台快照所示,它显示了服务器如何中继发起方发送的 SDP 描述和中继方检索到的 ICE 候选地址。 两个相互作用的同伴。

图5-14

图5-14 服务器引导的协商日志

最后,下面显示的 JavaScript 代码段指示两个对等点一从信令服务器到达,便立即将接收到的候选者添加到其自己的 PeerConnection 对象中:

  1. // Receive message from the other peer via the signaling server
  2. socket.on('message', function (message) {
  3. console.log('Received message:', message);
  4. if (message === 'got user media') {
  5. ...
  6. } else if (message.type === 'offer') {
  7. ...
  8. } else if (message.type === 'answer' && isStarted) {
  9. ...
  10. } else if (message.type === 'candidate' && isStarted) {
  11. var candidate = new RTCIceCandidate({
  12. sdpMLineIndex: message.label,
  13. candidate:message.candidate
  14. });
  15. pc.addIceCandidate(candidate);
  16. } else if (message === 'bye' && isStarted) {
  17. ...
  18. }
  19. });

一旦其他对等方收到 ICE 候选对象,便在 RTCPeerConnection 对象(setRemoteDescription)上设置了远程会话描述,因此 ICE 代理可以开始执行连接检查以查看它是否可以到达其他对等方。

此时,每个 ICE 代理都有其候选人和其同行候选人的完整列表。 将它们配对。 为了查看哪个对有效,每个代理计划安排一系列优先检查:首先检查本地 IP 地址,然后检查公共 IP 地址,最后使用 TURN。 每次检查都是客户端将通过从本地候选者向远程候选者发送 STUN 请求而对特定候选对执行的 STUN request/response 事务。

如果一对候选对象中的一个可行,则存在用于点对点连接的路由路径。 相反,如果所有候选项均失败,则 RTCPeerConnection 被标记为失败,或者连接回退到 TURN 中继服务器以建立连接。

建立连接后,ICE 代理会继续向其他对等方发出定期的 STUN 请求。 这用作连接保持活动状态。


ICE 流 (Trickle ICE)

ICE 流是 ICE 协议的推荐扩展,在此协议中,无需等待 ICE 收集过程完成,就可以向其他对等方发送增量更新。 这有助于加快整个设置阶段。

ICE 流 机制涉及以下步骤:

  • 双方交换没有 ICE 候选人的 SDP offer
  • 一旦发现 ICE 候选者,便通过信令信道发送它们。
  • 只要有新的候选者描述,便会运行 ICE 连接检查。