P2PTransportChannel · ICE 总指挥

P2PTransportChannel 是 ICE 的总指挥,把候选采集、配对、连通性检查、选路串成一台状态机。这一章读 base/p2p_transport_channel.h:它如何实现 IceTransportInternal、MaybeStartGathering 与 AddRemoteCandidate 两个入口、以及 gathering 与 transport 两套状态怎么演进到 connected/completed。

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

P2PTransportChannel · ICE 总指挥

前面几章的零件——候选、Port、STUN、Connection——都要有个总指挥把它们协同起来。这个总指挥就是 P2PTransportChannel(p2p/base/p2p_transport_channel.h)。它实现 IceTransportInternal 接口,是上一部分 JsepTransport 里那个 ICE 传输的真身。这一章看它怎么把 ICE 跑成一台状态机。

两个入口

P2PTransportChannel 对外的核心动作,是通话流程驱动的两个入口(p2p/base/p2p_transport_channel.h):

// p2p/base/p2p_transport_channel.h(节选)
void MaybeStartGathering() override;             // 开始采集候选
IceGatheringState gathering_state() const override;
void AddRemoteCandidate(const Candidate& candidate) override;  // 加入远端候选
IceTransportStateInternal GetState() const override;

一个管「采集与上报本地候选」,一个管「接纳远端候选并配对」——两股候选在 P2PTransportChannel 里汇合成一张连接网。

两套状态

P2PTransportChannel 维护两套状态,别混淆:

采集状态(gathering)和连接状态(transport)是两件事。

  • IceGatheringState —— 本地候选采集的进度:new(没开始)→ gathering(采集中)→ complete(采完了)。它只关心「我的候选找齐了没」。
  • IceTransportState(对应 W3C 的 RTCIceTransportState)—— 和对端连通的进度:new → checking(正在做连通性检查)→ connected(至少一条路通了)→ completed(检查全部完成、选定最优)→ 以及出问题时的 disconnected / failed / closed。

你在 PeerConnectionObserver 里分别收到 OnIceGatheringChange 和 OnIceConnectionChange 两组回调,对应的正是这两套状态。「候选采集完了」不等于「连上了」——你可能候选早采完,却还在苦苦检查;也可能候选还没采齐,就已经用先到的候选连上了(trickle 的好处)。分开建模,才能精确反映真实进度。

状态怎么演进

把建连五步落到 P2PTransportChannel 的状态机上:

图表加载中…

P2PTransportChannel 内部有个 SortConnectionsAndUpdateState——每当有 Connection 状态变化(变 writable、收到包、RTT 更新),它就重新给所有连接排序、更新自己的 transport 状态、并让 IceController 决定是否切换选中的连接。这个「排序 + 更新」是 ICE 动态适应网络的核心循环。

触发下游:连上了就握手

g3doc/ice.md 的建连第五步:一旦 P2PTransportChannel 首次选定一条连接、状态变化,它 SignalIceTransportStateChanged 向上通知——这会让上层的 DtlsTransport 意识到「路通了」,开始 DTLS 握手(第 3 部分)。至此 ICE 完成使命:它交出一条能通的、加密前的通路,媒体的加密与传输接力开始。

小结与下一章

P2PTransportChannel 是 ICE 总指挥(实现 IceTransportInternal),两个入口:MaybeStartGathering(采集本地候选)和 AddRemoteCandidate(接纳远端候选并配对成 Connection)。它维护两套状态——采集(new/gathering/complete)与连接(new/checking/connected/completed/failed/disconnected),分别对应 OnIceGatheringChange / OnIceConnectionChange。核心循环 SortConnectionsAndUpdateState 随连接变化重排、更新状态、驱动选路。连上后 SignalIceTransportStateChanged 触发 DTLS 握手。

它把「选哪条连接用、什么时候切」委托给了 IceController。下一章读这个选路大脑,以及 controlling / controlled 角色。👉 IceController:选路的大脑。

参考资料

  • [1] libwebrtc 源码.p2p/base/p2p_transport_channel.h / .cc(MaybeStartGathering、AddRemoteCandidate、GetState、SortConnectionsAndUpdateState)。
  • [2] libwebrtc 源码.p2p/base/ice_transport_internal.h(IceGatheringState / IceTransportState)、g3doc/ice.md。
  • [3] IETF RFC 8445「ICE」;W3C RTCIceTransportState。

本页目录