ICE(Interactive Connectivity Establishment,交互式连接建立)是一种 NAT穿透协议,在 WebRTC、VoIP 和视频会议等实时通信场景中被广泛使用。它的主要目标是解决由于 NAT(网络地址转换)和防火墙带来的连接问题,使通信双方能够建立可靠的端到端连接。
广泛用于:
其核心思想是:从多个路径中自动发现一条可用路径,并建立连接。
ICE 会收集本地、映射和中继地址作为候选:
类型 | 描述 | 优先级 | 是否穿透 |
---|---|---|---|
Host Candidate | 本地地址(如 192.168.x.x) | 高 | 否 |
Server Reflexive Candidate | 使用 STUN 获取的公网映射地址 | 中 | 是 |
Peer Reflexive Candidate | 连通性检查动态发现的对端地址 | 中等偏高 | 是 |
Relay Candidate | TURN 分配的地址,中继传输 | 低 | 是,最稳定 |
每个通信端收集自己的候选地址,包括:
ICE 候选优先级受以下因素影响:
priority = (2^24) * type preference +
(2^8) * local preference +
256 - component ID
pair_priority = 2^32 * min(local_priority, remote_priority) + 2 * max(...) + (local > remote ? 1 : 0)
WebRTC 使用 ICE 协议结合 STUN 和 TURN,在浏览器内部由 ICE Agent 实现,流程如下:
浏览器 A 信令通道 浏览器 B
────────────► Gather candidates ◄────────────
─────────────► Exchange SDP (包含 candidates) ◄─────────────
──────────────► Connectivity checks (STUN) ◄───────────────
───────────────► Nomination and Selection ◄───────────────
───────────────► 建立数据通道(DTLS + SRTP)◄──────────────
浏览器调用 WebRTC API(如 RTCPeerConnection
)时:
const pc = new RTCPeerConnection({
iceServers: [
{ urls: "stun:stun.l.google.com:19302" },
{ urls: "turn:your.turn.server", username: "...", credential: "..." }
]
});
通过 createOffer()
生成包含候选的 SDP,交换给对方。
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// 将 offer.sdp 通过信令(如 WebSocket)发送给对端
对端通过 setRemoteDescription()
接收 SDP 并回传 answer。
候选地址并不是一次性全部发送,而是逐步收集并发送(trickle ICE):
onicecandidate
事件触发时,每收集到一个 candidate 就发送给对端;addIceCandidate()
添加该地址。// 接收远端的 candidate
pc.addIceCandidate(new RTCIceCandidate(remoteCandidate));
ICE 建立连接后,WebRTC 进入安全协商阶段:
WebRTC 默认优先选择:
每个候选地址有一个类型优先级(type preference)和本地优先级(local preference)组成:
priority = (2^24) * typePref + (2^8) * localPref + (2^0) * componentId
WebRTC 默认使用此策略排序所有候选对并逐个测试。
可以监听 ICE 状态变化:
pc.oniceconnectionstatechange = () => {
console.log('ICE 状态:', pc.iceConnectionState);
};
状态可能值包括:
new
:未开始checking
:进行连通性检查connected
:至少有一个连接建立completed
:所有连接建立完毕(非 Trickle)disconnected
:网络临时中断failed
:连接失败closed
:连接已关闭步骤 | 关键点 |
---|---|
候选地址收集 | Host、STUN(Reflexive)、TURN(Relay) |
候选交换 | 通过 SDP + trickle ICE |
连通性检查 | STUN 探测路径可用性 |
优选与提名 | 基于优先级选最优地址对 |
连接建立 | 最终选中路径,建立 DTLS/SRTP |
协议 | 说明 |
---|---|
RFC 8445 | ICE 规范(最新) |
RFC 5245 | 旧版 ICE 标准 |
RFC 5389 | STUN 协议标准 |
RFC 5766 | TURN 协议标准 |
RFC 7589 | TURN over TCP |
优点 | 缺点 |
---|---|
适应多种网络环境,穿透强 | 实现复杂,调试难 |
自动化建立连接,提升体验 | TURN 中继性能和成本问题 |
标准成熟,兼容性好 | STUN、TURN 可用性影响大 |