ICE策略

WebRTC 中,ICE 的连接策略是可定制的。在 5.7.1 节中介绍 RTCPeerConnection 对象时,我们曾讲过可以给它传入一个 JSON 格式的参数但当时并没有对传入的参数做详细的介绍。现在我们来介绍该参数。

构造 RTCPeerConnection 对象时,其输入参数的类型为 RTCConfigurationRTCConfigurationWebRTC 规范中的定义参见代码 6.1。

代码6.1 RTCConfiguration 结构体
dictionary RTCConfiguration {
  sequence<RTCIceServer> iceServers;
  RTCIceTransportPolicy iceTransportPolicy;
  RTCBundlePolicy bundlePolicy;
  RTCRtcpMuxPolicy rtcpMuxPolicy;
  sequence<RTCCertificate> certificates;
  [EnforceRange] octet iceCandidatePoolSize = 0;
};

下面详细解释一下 RTCConfiguration 结构中各字段的含义,如表 6.1 所示。

image 2025 02 23 11 28 30 400
Figure 1. 表6.1 RTCConfiguration 各字段含义

通过表 6.1,我们已经对 RTCConfiguration 中各字段的含义了解得非常清楚了。不过,其中的 iceServers 字段还需要再解释一下。iceServersRTCIceServer 类型的数组,RTCIceServer 结构定义参见代码 6.2。

代码6.2 RTCIceServer结构体
dictionary RTCIceServer {
  required (DOMString or sequence<DOMString>) urls;
  DOMString username;
  DOMString credential;
  RTCIceCredentialType credentialType = "password";
};

该结构中各字段的含义如下:url,指明了服务的地址;usernamecredential,指明了访问 url 地址时使用的用户名和密码;credentialType,指明授权方式为密码方式,也是目前唯一的授权方式。

了解了上面这些内容后,再来看一下具体的例子,看看在真实场景中是如何使用 RTCConfiguration 的,具体如代码 6.3 所示。

代码6.3 PeerConnection配置
var pcConfig = {
  iceServers: [
    {
      urls: 'turn:stun.learningrtc.cn:3478',
      username: 'username1',
      credential: 'password1'
    },
    {
      urls: 'turn:stun.avdancedu.com:3478',
      username: 'username2',
      credential: 'password2'
    }
  ],
  iceTransportPolicy: 'all',
  bundlePolicy: 'max-bundle',
  rtcpMuxPolicy: 'require'
};

let pc = new RTCPeerConnection(pcConfig);

// ...

在上面的 RTCConfiguration 对象中,包含了两个 TURN 服务器,分别是 stun.learningrtc.cnstun.avdancedu.com,相当于为 WebRTC 增加了两个 relay 类型的 Candidate。当内网和 P2P 无法连通时,RTCPeerConnection 会尝试与这两台中继服务器连接,如果其中一台连接成功,就不再尝试连接另一台。

示例中,除了设置多个 TURN 服务器外,在 RTCConfiguration 中还将 iceTransportPolicy 字段设置为 all,表示按 Candidate 优先级次序尝试连接;bundlePolicy 设置为 max-bundle,表示让所有媒体数据使用同一个 Candidate,这样更有利于端口资源的利用;rtcpMuxPolicy 设置为 require,表示 RTCPRTP 数据共用同一个 Candidate