WebRTC(六):ICE协议

发布于:2025-06-19 ⋅ 阅读:(19) ⋅ 点赞:(0)

协议简介

ICE(Interactive Connectivity Establishment,交互式连接建立)是一种 NAT穿透协议,在 WebRTC、VoIP 和视频会议等实时通信场景中被广泛使用。它的主要目标是解决由于 NAT(网络地址转换)和防火墙带来的连接问题,使通信双方能够建立可靠的端到端连接。

广泛用于:

  • WebRTC(浏览器实时通信)
  • VoIP(语音通话)
  • 视频会议系统
  • P2P 文件传输系统

其核心思想是:从多个路径中自动发现一条可用路径,并建立连接

核心目标

  • 发现并测试连接路径:通过不同网络路径和地址尝试建立连接。
  • NAT穿透:穿越 NAT 和防火墙建立点对点连接。
  • 选择最佳连接路径:根据连通性检查的结果选择延迟最低、可用性最好的候选地址对。
  • 必要时使用 TURN 进行中继

基本概念

Candidate(候选地址)

ICE 会收集本地、映射和中继地址作为候选:

类型 描述 优先级 是否穿透
Host Candidate 本地地址(如 192.168.x.x)
Server Reflexive Candidate 使用 STUN 获取的公网映射地址
Peer Reflexive Candidate 连通性检查动态发现的对端地址 中等偏高
Relay Candidate TURN 分配的地址,中继传输 是,最稳定

STUN(Session Traversal Utilities for NAT)

  • 用于查询 NAT 映射后的公网地址,获取 Server Reflexive Candidate。
  • 提供最轻量级的 NAT 穿透方式。

TURN(Traversal Using Relays around NAT)

  • 当 STUN 穿透失败时,TURN 中继服务器作为数据转发中介。
  • 成本高,延迟大,但可靠性高。

ICE Agent

  • 每个通信端都运行一个 ICE Agent,它负责候选地址的收集、连通性检查、优先级比较、协商等工作。

工作流程

步骤 1:候选地址收集(Gathering)

每个通信端收集自己的候选地址,包括:

  • 本地地址(Host)
  • STUN服务器反射地址(Server Reflexive)
  • TURN中继地址(Relay)

步骤 2:交换候选地址(Candidate Exchange)

  • 使用信令协议(如 SDP,通常通过 SIP、WebRTC 的信令通道)交换候选地址。

步骤 3:连通性检查(Connectivity Checks)

  • 使用 STUN 消息对候选地址对(candidate pair)进行测试,看是否能成功通信。
  • 成功的连接对会被 ICE 标记为可用。

步骤 4:选择优选连接路径

  • 每对候选地址都有优先级(由 ICE 算法计算得出)。
  • ICE 会选择具有最高优先级且可达的候选对作为最终连接路径。

步骤 5:建立连接(Nomination)

  • 确认并锁定最终使用的候选对。
  • 对于双向通信(例如 WebRTC 的数据通道),双方都要确认连接对。

优先级与候选对选择

ICE 候选优先级受以下因素影响:

  • 地址类型优先级:Host > Server Reflexive > Relay
  • 网络接口类型:有线 > 无线
  • 类型偏好(type preference)
  • 本地优先级(local preference)

单个候选优先级

priority = (2^24) * type preference +
           (2^8)  * local preference +
           256 - component ID
  • Type Preference:Host > Reflexive > Relay
  • Local Preference:用于多网卡排序
  • Component ID:RTP/RTCP 区分

候选对优先级(candidate pair)

pair_priority = 2^32 * min(local_priority, remote_priority) + 2 * max(...) + (local > remote ? 1 : 0)

WebRTC 中 ICE 实现

整体架构

WebRTC 使用 ICE 协议结合 STUNTURN,在浏览器内部由 ICE Agent 实现,流程如下:

浏览器 A                      信令通道                    浏览器 B
────────────► Gather candidates ◄────────────
─────────────► Exchange SDP (包含 candidates) ◄─────────────
──────────────► Connectivity checks (STUN) ◄───────────────
───────────────► Nomination and Selection ◄───────────────
───────────────► 建立数据通道(DTLS + SRTP)◄──────────────

ICE 流程详解(WebRTC 版本)

步骤 1:候选地址收集(ICE Gathering)

浏览器调用 WebRTC API(如 RTCPeerConnection)时:

  • 浏览器会自动:
    • 检查本地网络接口,生成 Host 候选地址
    • 使用配置的 STUN 服务器获取 Server Reflexive 地址
    • 使用配置的 TURN 服务器申请 Relay 候选地址
const pc = new RTCPeerConnection({
  iceServers: [
    { urls: "stun:stun.l.google.com:19302" },
    { urls: "turn:your.turn.server", username: "...", credential: "..." }
  ]
});

步骤 2:信令交换(SDP 内部包含候选地址)

通过 createOffer() 生成包含候选的 SDP,交换给对方。

const offer = await pc.createOffer();
await pc.setLocalDescription(offer);

// 将 offer.sdp 通过信令(如 WebSocket)发送给对端

对端通过 setRemoteDescription() 接收 SDP 并回传 answer。

步骤 3:候选地址交换(Trickle ICE)

候选地址并不是一次性全部发送,而是逐步收集并发送(trickle ICE)

  • onicecandidate 事件触发时,每收集到一个 candidate 就发送给对端;
  • 对端通过 addIceCandidate() 添加该地址。
// 接收远端的 candidate
pc.addIceCandidate(new RTCIceCandidate(remoteCandidate));

步骤 4:连通性检查(STUN 交叉测试)

  • 双方根据候选地址对进行连通性检查(connectivity check)
  • 使用 STUN Binding Request 消息进行握手;
  • 浏览器使用 STUN over UDP/TCP 判断路径可用性;
  • 若某对候选可通信,则标记为成功。

步骤 5:候选优选(Nomination)

  • 每个候选对被赋予优先级;
  • 浏览器选择最优的一对进行“提名”(nomination);
  • 一旦确认,浏览器锁定该候选对用于媒体通信。

步骤 6:连接建立并切换至 DTLS/SRTP

ICE 建立连接后,WebRTC 进入安全协商阶段:

  • 使用 DTLS(Datagram TLS)建立安全数据通道;
  • 使用 SRTP 加密媒体流;
  • 数据通道使用 SCTP over DTLS。

候选地址优先级逻辑(WebRTC)

WebRTC 默认优先选择:

  1. Host(最快,最原始);
  2. Reflexive(可 NAT 穿透);
  3. Relay(TURN,中继,最慢但最稳定);

每个候选地址有一个类型优先级(type preference)和本地优先级(local preference)组成:

priority = (2^24) * typePref + (2^8) * localPref + (2^0) * componentId

WebRTC 默认使用此策略排序所有候选对并逐个测试。

ICE 状态机(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 可用性影响大

网站公告

今日签到

点亮在社区的每一天
去签到