RTCIceCandidate:usernameFragment 属性

Baseline 已广泛支持

此特性已得到良好支持,可在多种设备和浏览器版本上使用。自 2021 年 4 月起,所有浏览器均已支持此特性。

RTCIceCandidate 接口上只读的 usernameFragment 属性是一个字符串,用于表示用户名片段 ("ufrag"),它唯一标识单个 ICE 交互会话。

此值通过传递给 RTCIceCandidate() 构造函数的 candidateInfo 选项对象中的 usernameFragment 属性来指定。如果使用 m-line 字符串而不是选项对象调用构造函数,则 usernameFragment 的值将从指定的候选 m-line 字符串中提取。

请注意,浏览器需要对用户名片段的 24 位进行随机化。有关详细信息,请参阅下面的 随机化

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

随机化

在 ICE 会话开始时,ICE 层需要随机选择 ufrag 中文本的至少 24 位。具体哪些位是随机的以及 ufrag 文本的其余部分由浏览器实现决定。例如,浏览器可能选择始终使用一个 24 个字符的 ufrag,其中每个字符的第 4 位在 0 和 1 之间随机选择。另一个例子:它可能会获取一个用户定义的字符串,并在末尾附加三个 8 位随机字节。或者,也许每个字符都是完全随机的。

用法说明

ICE 使用 usernameFragment 和密码来确保消息的完整性。这可以避免多个正在进行的 ICE 会话之间的串扰,但更重要的是,有助于保护 ICE 事务(以及由此扩展的所有 WebRTC)免受可能试图将自身注入 ICE 交换的攻击。

注意: 出于显而易见的安全原因,没有 API 可以获取 ICE 密码。

每次发生 ICE 重新启动时,usernameFragment 和密码都会发生变化。

示例

尽管 WebRTC 基础设施会在 ICE 重新启动后为您过滤掉过时的候选者,但如果您想将来回传递的消息数量降至最低,也可以自己进行过滤。

为此,在收到来自信令服务器的候选者并调用 addIceCandidate() 将其添加到候选集之前,您可以比较 usernameFragment 的值与当前连接正在使用的 usernameFragment

当 Web 应用从信令服务器接收到包含要添加到 RTCPeerConnection 的候选者的消息时,您可以(并且通常应该)调用 addIceCandidate()。通常不需要手动处理候选者的过滤。

但是,让我们设想我们需要最小化流量。下面的函数 ssNewCandidate() 在从信令服务器收到包含要添加到 RTCPeerConnection 的 ICE 候选者的消息 signalMsg 时被调用。为了避免包含被 ICE 重新启动所淘汰的候选者,我们可以使用如下代码:

js
const ssNewCandidate = (signalMsg) => {
  const candidate = new RTCIceCandidate(signalMsg.candidate);
  const receivers = pc.getReceivers();

  for (const receiver of receivers) {
    const parameters = receiver.transport.iceTransport.getRemoteParameters();

    if (parameters.usernameFragment === candidate.usernameFragment) {
      return;
    }
  }

  pc.addIceCandidate(candidate).catch(window.reportError);
};

这会遍历用于接收 ICE 数据的 RTCRtpReceiver 对象列表,并检查候选者中指示的 usernameFragment 是否与其中任何一个匹配。如果匹配,则 ssNewCandidate() 会中止。否则,在检查完所有接收器后,它会将新的候选者添加到连接中。

规范

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

浏览器兼容性