WebRTC 的 ICE(Interactive Connectivity Establishment)是一个用于建立和优化点对点连接的机制。它的主要功能是帮助两台设备在复杂的网络环境中(例如通过 NAT 或防火墙)找到并使用最有效的通信路径。
一、收集候选地址
ICE(Interactive Connectivity Establishment,互动连接建立)是 WebRTC 和其他实时通信协议中用来解决 NAT 穿越问题的关键机制,首先是在于本机对自身的候选地址的收集:
1. 本地候选地址
这是本地网络接口的直接 IP 地址。例如,如果设备连接到 Wi-Fi,那么这个候选地址就是 Wi-Fi 接口的 IP 地址。
WebRTC 会收集 IPv4 和 IPv6 的地址。
a=candidate:1 1 udp 2122260223 192.168.1.2 56143 typ host generation 0
2. 与 STUN 服务器交互以获取反射候选地址
由于 NAT 设备通常会对内部 IP 地址进行隐藏,因此 WebRTC 客户端需要与 STUN 服务器交互,以获取 NAT 后的公共 IP 地址。这个公共地址称为反射候选地址。客户端向 STUN 服务器发送请求,STUN 服务器将请求的来源 IP 地址和端口返回给客户端。这些信息就是 NAT 后的公共 IP 地址。
反射候选地址可以用于穿越对称 NAT 和大多数的家庭路由器。
a=candidate:2 1 udp 1686052607 203.0.113.1 3478 typ srflx raddr 192.168.1.2 rport 56143 generation 0
3. 可选:与 TURN 服务器交互以获取中继候选地址
在一些情况下,直接 P2P 连接可能无法建立,例如在对称 NAT 或防火墙阻止 UDP 的情况下。为了确保连接的成功,WebRTC 可能会使用 TURN 服务器。客户端向 TURN 服务器申请一个中继地址,TURN 服务器会为客户端分配一个中继 IP 地址和端口。
所有的媒体流量将通过 TURN 服务器中继,作为最后的备用手段。
a=candidate:3 1 udp 1518283007 203.0.113.10 3479 typ relay generation 0
二、ICE 候选路径的优先级和选择机制
WebRTC 在进行 P2P 连接时,双方会交换 candidate
信息,建立可能的传输路径。这些路径由 ICE 代理进行打洞(NAT 穿越)和测试,最终选择一条最优的路径进行媒体流的传输。
1. 候选路径的收集
a=candidate:1 1 udp 2122260223 192.168.1.2 56143 typ host generation 0
a=candidate:2 1 udp 1686052607 203.0.113.1 3478 typ srflx raddr 192.168.1.2 rport 56143 generation 0
a=candidate:3 1 udp 1518283007 203.0.113.10 3479 typ relay generation 0
2. 路径优先级的计算
每个候选路径都会有一个优先级,优先级的计算公式为:
优先级=(2^24 × 候选类型优先级) + (2^8 × 本地优先级) + (256 − 组件 ID)
优先级越高的候选路径将被优先测试。一般来说,本地主机候选的优先级最高,其次是反射候选,最后是中继候选。
3. 路径的测试和选择
连接检查:ICE 代理会同时测试多个候选路径,发送 STUN 探测请求,确认路径的可达性。
最佳路径的选择:一旦某个候选路径成功通过连接测试并返回 STUN 响应,WebRTC 会选择该路径作为最终的传输路径。如果有多个路径成功,优先选择优先级最高的路径。
4. 动态调整
WebRTC 具有动态调整的能力。如果当前的网络环境发生变化(例如网络切换),ICE 会重新收集新的候选路径,并根据新的候选重新进行连接检查,从而选择新的最优路径。
三、candidate说明
1. a=candidate:1 1 udp 2122260223 192.168.1.2 56143 typ host generation 0
编号 '1': 这是第一个候选路径。
'1': 这个数字表示候选路径是针对 RTP(Real-time Transport Protocol)流的组件编号。
'udp': 使用的传输协议是 UDP(User Datagram Protocol)。
'2122260223': 这个数字是候选路径的优先级,优先级越高,路径越有可能被选中。
'192.168.1.2': 这是本地主机的 IP 地址,表示这个候选路径是在本地网络内的地址。
'56143': 这是本地主机上的 UDP 端口号。
'typ host': 这个路径类型是 host,意味着这是一个直接可用的本地地址。
'generation 0': 这表明候选路径属于第 0 代,通常用于指代 SDP 中的 ICE generation。
2. a=candidate:2 1 udp 1686052607 203.0.113.1 3478 typ srflx raddr 192.168.1.2 rport 56143 generation 0
编号 '2': 这是第二个候选路径。
'1': 组件编号,依然针对 RTP 流。
'udp': 使用的传输协议是 UDP。
'1686052607': 这是该候选路径的优先级。
'203.0.113.1': 这是经过 NAT 后的公共 IP 地址,也称为反射地址(Server Reflexive)。
'3478': 这是公共 IP 地址上的 UDP 端口号。
'typ srflx': 这个路径类型是 srflx,表示它是一个从 STUN 服务器获取的反射地址,用于 NAT 穿越。
'raddr 192.168.1.2': 反射地址对应的本地 IP 地址(即候选路径 1 中的本地地址)。
'rport 56143': 反射地址对应的本地端口号(与候选路径 1 中的端口相同)。
'generation 0': 同样属于第 0 代。
3. a=candidate:3 1 udp 1518283007 203.0.113.10 3479 typ relay generation 0
编号 '3': 这是第三个候选路径。
'1': 组件编号,依然针对 RTP 流。
'udp': 使用的传输协议是 UDP。
'1518283007': 这是该候选路径的优先级。
'203.0.113.10': 这是 TURN 服务器提供的中继 IP 地址。
'3479': 这是中继 IP 地址上的 UDP 端口号。
'typ relay': 这个路径类型是 relay,表示它通过 TURN 服务器中继数据,用于绕过 NAT 或防火墙。
'generation 0': 仍属于第 0 代。