RTCPeerConnection: addIceCandidate() 方法

Baseline 已广泛支持

此功能已成熟,可跨多种设备和浏览器版本使用。自 2017 年 9 月以来,它已在浏览器中提供。

RTCPeerConnection 接口的 addIceCandidate() 方法会将一个新的远程候选添加到连接的远程描述中,该描述描述了连接远程端的状态。

当使用 RTCPeerConnection 的网站或应用程序通过其信令通道从远程对等方接收到新的 ICE 候选时,它会通过调用 RTCPeerConnection.addIceCandidate() 将新收到的候选传递给浏览器的 ICE 代理。这会将此新的远程候选添加到 RTCPeerConnection 的远程描述中,该描述描述了连接远程端的状态。

如果在调用 addIceCandidate()candidate 参数缺失或值为 null,则添加的 ICE 候选是一个“结束候选”指示符。如果指定对象的 candidate 属性的值缺失或为空字符串 (""),也表示所有远程候选都已传递完毕。

通过具有 end-of-candidates a-line 值的候选来向远程对等方传输结束候选通知。

在协商过程中,您的应用程序可能会收到许多候选,您将通过这种方式将它们传递给 ICE 代理,使其能够构建潜在连接方法的列表。这在 WebRTC 连接信令和视频通话 文章中有更详细的介绍。

语法

js
addIceCandidate(candidate)

addIceCandidate(candidate, successCallback) // deprecated
addIceCandidate(candidate, successCallback, failureCallback) // deprecated

参数

candidate 可选

一个 RTCIceCandidate 对象,或一个具有以下属性的对象

candidate 可选

一个描述候选属性的字符串,直接取自 SDP 属性 "candidate"。候选字符串指定候选的网络连接信息。如果 candidate 为空字符串 (""),则表示已到达候选列表的末尾;此候选称为“结束候选”标记。

候选字符串的语法在 RFC 5245, section 15.1 中进行了描述。对于如下 a-line (属性行):

a=candidate:4234997325 1 udp 2043278322 192.0.2.172 44323 typ host

相应的 candidate 字符串的值将是:

"candidate:4234997325 1 udp 2043278322 192.0.2.172 44323 typ host"`

在所有条件都相同的情况下,用户代理总是优先选择具有最高 priority 的候选。在上面的示例中,优先级是 2043278322。属性之间都用单个空格字符分隔,并且顺序是固定的。此示例候选的完整属性列表是:

更多信息可以在 RTCIceCandidate.candidate 中找到。

注意:为了向后兼容 WebRTC 规范的旧版本,构造函数也接受此字符串作为参数。

sdpMid 可选

一个包含与候选关联的媒体流的标识符标签的字符串,如果没有关联的媒体流则为 null。默认值为 null

更多信息可以在 RTCIceCandidate.sdpMid 中找到。

sdpMLineIndex 可选

一个数字属性,包含与候选关联的 m-line 在媒体描述的 SDP 中的零基索引,如果没有此类关联则为 null。默认值为 null

更多信息可以在 RTCIceCandidate.sdpMLineIndex 中找到。

usernameFragment 可选

一个包含用户名片段(通常简称为“ufrag”或“ice-ufrag”)的字符串。此片段与 ICE 密码(“ice-pwd”)一起,唯一标识单个正在进行的 ICE 交互(包括与 STUN 服务器的任何通信)。

该字符串由 WebRTC 在会话开始时生成。其长度最多可达 256 个字符,并且至少 24 位必须包含随机数据。它没有默认值,除非显式设置,否则不存在。

更多信息可以在 RTCIceCandidate.usernameFragment 中找到。

如果 sdpMidsdpMLineIndex 都为 null,则该方法将抛出 TypeError 异常。

对象的内容应由通过信令通道接收到的消息构建,该消息描述了一个已准备好传递给本地 ICE 代理的新收到的 ICE 候选。

如果未指定 candidate 对象,或其值为 null,则使用 end-of-candidates a-line 向远程对等方发送结束候选信号,格式如下:

a=end-of-candidates

已弃用的参数

在旧代码和文档中,您可能会看到该函数的基于回调的版本。该版本已被弃用,并且**强烈**不建议使用。您应该更新任何现有代码以使用 addIceCandidate() 的基于 Promise 的版本。为了帮助更新现有代码,下面描述了旧版 addIceCandidate() 的参数。

successCallback 已弃用

当 ICE 候选成功添加时调用的函数。此函数不接收任何输入参数,也不返回值。

failureCallback 已弃用

尝试添加 ICE 候选失败时调用的函数。接收一个 DOMException 对象作为输入,描述失败原因。

返回值

当 ICE 代理成功将候选添加到远程对等方的描述中时,此方法返回的 Promise 会被 fulfilled。Promise 不接收任何输入参数。

异常

当尝试添加 ICE 候选时发生错误,此方法返回的 Promise 会被 rejected,将以下错误之一作为指定 DOMException 对象中 name 属性的值传递给 rejection handler。

TypeError

如果指定的候选的 sdpMidsdpMLineIndex 都为 null,则返回此错误。

InvalidStateError DOMException

如果 RTCPeerConnection 当前没有已建立的远程对等方(remoteDescriptionnull),则返回此错误。

OperationError DOMException

在以下任一情况发生时返回:

  • sdpMid 指定的值非 null,且与 remoteDescription 中包含的任何媒体描述的媒体描述 ID 不匹配。
  • 指定的 sdpMLineIndex 值大于或等于远程描述中包含的媒体描述数量。
  • 指定的 ufrag 与正在考虑的任何远程描述中的 ufrag 字段不匹配。
  • candidate 字符串中的一个或多个值无效或无法解析。
  • 尝试添加候选因任何原因失败。

示例

此代码片段显示了如何通过任意信令通道信令 ICE 候选。

js
// This example assumes that the other peer is using a signaling channel as follows:
//
// pc.onicecandidate = (event) => {
//   if (event.candidate) {
//     signalingChannel.send(JSON.stringify({ice: event.candidate})); // "ice" is arbitrary
//   } else {
//     // All ICE candidates have been sent
//   }
// }

signalingChannel.onmessage = (receivedString) => {
  const message = JSON.parse(receivedString);
  if (message.ice) {
    // A typical value of ice here might look something like this:
    //
    // {candidate: "candidate:0 1 UDP 2122154243 192.0.2.43 53421 typ host", sdpMid: "0", …}
    //
    // Pass the whole thing to addIceCandidate:

    pc.addIceCandidate(message.ice).catch((e) => {
      console.log(`Failure during addIceCandidate(): ${e.name}`);
    });
  } else {
    // handle other things you might be signaling, like sdp
  }
};

远程对等方通过此方式信令的最后一个候选将是一个特殊的候选,表示结束候选。出于兴趣,可以使用以下方法手动指示结束候选:

js
pc.addIceCandidate({ candidate: "" });

然而,在大多数情况下,您不需要显式查找它,因为驱动 RTCPeerConnection 的事件会为您处理它,发送相应的事件。

规范

规范
WebRTC:浏览器中的实时通信
# dom-peerconnection-addicecandidate

浏览器兼容性

另见