RTCPeerConnection: addIceCandidate() 方法

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

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

如果调用 addIceCandidate()candidate 参数缺失或提供的值为 null,则添加的 ICE 候选者是“候选者结束”指示器。如果指定对象的 candidate 值缺失或为空字符串 (""),情况也是如此,它表示所有远程候选者都已经传递。

候选者结束通知是使用具有 end-of-candidates a 行值的候选者传输到远程对等方的。

在协商期间,您的应用程序可能会收到许多候选者,您将以这种方式将它们传递给 ICE 代理,使其能够构建潜在连接方法的列表。在文章 WebRTC 连接信令与视频通话 中对此进行了更详细的说明。

语法

js
addIceCandidate(candidate)

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

参数

candidate 可选

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

candidate 可选

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

候选者字符串的语法在 RFC 5245,第 15.1 节 中描述。对于看起来像这样的 a 行(属性行)

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 行的零基索引的数字属性,该索引在媒体描述的 SDP 中,或者如果不存在关联的 m 行,则为 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 行向远程对等方发送候选者结束信号,格式如下

a=end-of-candidates

已弃用的参数

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

successCallback 已弃用

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

failureCallback 已弃用

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

返回值

一个 Promise,当候选者被 ICE 代理成功添加到远程对等方的描述时,该 Promise 将被完成。该 Promise 不接收任何输入参数。

异常

当尝试添加 ICE 候选者时发生错误时,此方法返回的 Promise 将被拒绝,并返回以下错误之一作为指定的 DOMException 对象传递给拒绝处理程序的 name 属性。

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

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参见