提名与 ICE 重启 · 拍板与重来

控制方怎么「拍板」选定一条路?靠提名——在 STUN 探测里带上 USE-CANDIDATE。而网络剧变、连接彻底断掉时,ICE 还能整个重启重来。这一章讲常规提名 vs 激进提名、ICE 重启换新凭据重新采集,以及持续采集如何支撑移动场景。

作者 David更新于 第 24 篇(共 112 篇)

提名与 ICE 重启 · 拍板与重来

上一章说 controlling 角色「拍板」选路。它具体怎么拍板?靠提名(nomination)。而当网络发生剧变、选中的路彻底断掉,ICE 还有一招兜底:整个重启。这两个机制,一个管「正常怎么定下来」,一个管「出大事怎么重来」。

提名:在探测里插一面小旗

控制方选定要用哪条 Connection 后,怎么告诉对端「就用这条」?它在发给这条连接的 STUN Binding 请求里,带上一个 USE-CANDIDATE 属性——相当于插了一面小旗:「这条,钦定了」。受控方收到带旗的探测,就知道这条被提名了。这正是 Connection::nominated() 标记的东西。

提名有两种风格,base/connection.h 的注释就提到「Regular or Aggressive」:

常规提名 vs 激进提名——「谋定后动」还是「边打边定」。

  • 常规提名(Regular) —— 控制方先把连通性检查做得差不多,看清哪条最优,再发一轮带 USE-CANDIDATE 的探测正式提名它。稳妥,但多一个来回,慢一点。
  • 激进提名(Aggressive) —— 控制方在每个探测上都带 USE-CANDIDATE,边检查边提名——第一条通的路立刻就被「提名」用上。快,但可能先用上一条次优的路,之后再切到更好的。

权衡是建连速度 vs 选路质量:激进提名让媒体尽快流动(用户体验好),代价是初期可能不是最优路径,靠后续的持续选路慢慢优化到最好。现代 WebRTC 倾向于「快速可用、再逐步优化」,所以激进提名很常见。一条连接既 writable 又被 nominated,就成了「选中的连接」,媒体从它走。

ICE 重启:推倒重来

选定的路不是永久的。手机从 Wi-Fi 走到电梯里断网、网络切换、NAT 映射被回收……选中的连接可能彻底 TIMEOUT,所有连接都废了。这时需要ICE 重启(ICE restart):

ICE 重启 = 换一套全新的 ICE 凭据,把采集和检查从头再来一遍。 具体地:生成新的 ice-ufrag / ice-pwd(凭据),发起一轮新的 offer/answer 协商带上新凭据;P2PTransportChannel 开一个全新的 PortAllocatorSession 重新采集候选、重新配对检查。新凭据是关键——它让新一轮的 STUN 探测和旧的区分开,老连接的残留探测不会干扰新会话。

重启期间,旧连接若还能用会继续撑着,直到新连接就绪才切换,尽量不中断通话。这就是为什么你在地铁里视频通话,网络抖一下、卡几秒,却往往能自己缓过来——底层正在默默地 ICE 重启,重新为你找一条能通的路。

持续采集:为移动而生

还有一个和重启相关的机制:持续采集(continual gathering)。默认情况下候选采集完就停了(gathering complete);但开启持续采集后,PortAllocator 会一直盯着网络变化——新网卡上线(插了网线、连上新 Wi-Fi)就采集新候选并 trickle 给对端,老网卡下线就移除相关候选。这让 ICE 能不重启就适应网络变化:多一条新路可用时,选路自然会考虑它、必要时切过去。持续采集 + 动态选路,共同支撑了 WebRTC 的移动性——设备网络环境一直在变,通话却能持续。

图表加载中…

小结与下一章

提名是控制方「拍板」的方式:在 STUN 探测里带 USE-CANDIDATE(即 nominated())。常规提名谋定后动(稳、慢),激进提名边打边定(快、可能次优再优化)。ICE 重启在连接全断时推倒重来:换新 ufrag/pwd、开新 PortAllocatorSession 重采重检,旧连接撑到新的就绪。持续采集盯着网络变化、动态增删候选,和动态选路一起支撑移动性——这也是地铁里通话能自己缓过来的原因。

而「网络变化」这件事,谁来感知?是 rtc_base 里的 NetworkManager。它枚举网卡、监测变化,是 ICE 移动性的眼睛。下一章收尾第 2 部分。👉 网络监测:NetworkManager。

参考资料

  • [1] libwebrtc 源码.p2p/base/connection.h(nominated、Regular/Aggressive 注释)、p2p/base/p2p_transport_channel.cc(ICE 重启、持续采集)。
  • [2] libwebrtc 源码.p2p/base/port_allocator.h(PortAllocatorSession、continual gathering)。
  • [3] IETF RFC 8445「ICE」§ Nominating、ICE Restart;RFC 8838「Trickle ICE」。

本页目录