RTCDtlsTransport - 提供对有关数据报传输层安全性(DTLS)传输的信息的访问

RTCDtlsTransport 接口提供对有关数据报传输层安全性(Datagram Transport Layer Security)(DTLS)传输的信息的访问,RTCPeerConnectionRTPRTCP数据包通过其 RTCRtpSenderRTCRtpReceiver 对象发送和接收。

DTLS 传输还用于提供有关由连接的数据通道发送和接收的 SCTP 数据包的信息。

DTLS 传输的功能包括为基础传输增加安全性;RTCDtlsTransport 接口可用于获取有关基础传输的信息以及 DTLS 层为其添加的安全性。

描述

DTLS 传输的分配

当应用调用 setLocalDescription()setRemoteDescription() 时,将创建 RTCDtlsTransport 对象。创建的 DTLS 传输的数量及其使用方式取决于创建 RTCPeerConnection 时使用的捆绑模式。

是否使用捆绑取决于其他端点能够协商的内容。所有浏览器都支持捆绑,因此当两个端点都是浏览器时,您可以放心,将使用捆绑。

但是,某些非浏览器的旧式端点可能不支持捆绑。为了能够与此类端点进行协商(或将其完全排除),可以在创建连接时指定 RTCConfiguration 属性 bundlePolicy 连接。bundlePolicy 使您可以控制如何与这些旧式端点进行协商。默认策略是 "balanced",可以在性能和兼容性之间取得平衡。

例如,要使用最高级别的捆绑创建连接:

const rtcConfig = {
  bundlePolicy: "max-bundle"
};

const pc = new RTCPeerConnection(rtcConfig);

捆绑使您可以使用一个 RTCDtlsTransport 来携带多个更高级别传输的数据,例如多个 RTCRtpTransceiver

不使用捆绑时

在不使用捆绑的情况下创建连接时,每个 RTCRtpTransceiver 的每个 RTP 或 RTCP 组件都有其自己的 RTCDtlsTransport;也就是说,每个 RTCRtpSenderRTCRtpReceiver 都有自己的传输,并且所有 RTCDataChannel 对象共享一个专用于 SCTP 的传输。

使用捆绑时

当连接使用捆绑软件时,每个 RTCDtlsTransport 对象代表一组 RTCRtpTransceiver 对象。如果连接是使用 max-compat(最大兼容)模式创建的,则每个传输负责处理给定类型的媒体(音频,视频或数据通道)的所有通信。因此,具有任意数量的音频和视频通道的连接将始终仅具有一个用于音频的 DTLS 传输和一个用于视频通信的 DTLS 传输。

由于传输是在协商过程的早期建立的,所以很可能在远程对等点是否支持绑定之前都不会知道它的存在。因此,您有时会看到最初创建单独的传输,每个音轨一个,然后在知道可以绑定时就将它们捆绑起来。

如果您的代码直接访问 RTCRtpSender 和/或 RTCRtpReceiver,则可能会遇到它们最初分开的情况,然后它们中的一半或更多将被关闭,并且发送方和接收方将更新为引用剩下的 RTCDtlsTransport 对象。

数据通道

RTCDataChannel 使用 SCTP 进行通信。对等连接的所有数据通道共享一个单独的 RTCSctpTransport,该属性位于连接的 sctp 属性中。

然后,您可以通过查看 RTCSctpTransport 对象的 transport 属性来识别用于安全封装数据通道 SCTP 通信的 RTCDtlsTransport

实例

这个例子展示了一个函数 tallySenders(),该函数对 RTCPeerConnectionRTCRtpSender 上进行遍历,统计它们的状态。该函数返回一个包含属性的对象,这些属性的值指示每种状态下有多少个发送者。

let pc = new RTCPeerConnection({ bundlePolicy: "max-bundle" });

/* ... */

function tallySenders(pc) {
  let results = {
    transportMissing: 0,
    connectionPending: 0,
    connected: 0,
    closed: 0,
    failed: 0,
    unknown: 0
  };

  let senderList = pc.getSenders();
  senderList.forEach(sender => {
    let transport = sender.transport;

    if (!transport) {
      results.transportMissing++;
    } else {
      switch(transport.state) {
        case "new":
        case "connecting":
          results.connectionPending++;
          break;
       case "connected":
          results.connected++;
          break;
       case "closed":
          results.closed++;
          break;
       case "failed":
          results.failed++;
          break;
       default:
          results.unknown++;
          break;
      }
    }
  });
  return results;
}

请注意,在这段代码中,newconnecting 状态在返回的对象中被合并为 connectionPending 状态。

规范

规范 状态 备注
WebRTC 1.0: Real-time Communication Between Browsers
RTCDtlsTransport 的定义
候选推荐 初始定义。

桌面浏览器兼容性

特性ChromeEdgeFirefoxInternet ExplorerOperaSafari
基础支持7212 不支持1 不支持60 不支持
getRemoteCertificates7212 不支持1 不支持60 不支持
iceTransport72152 不支持1 不支持60 不支持
onerror7212 不支持1 不支持60 不支持
onstatechange72123 不支持1 不支持60 不支持
state7212 不支持1 不支持60 不支持
statechange 事件72124 不支持1 不支持60 不支持

移动浏览器兼容性

特性AndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
基础支持7272 未知 不支持1 未知50 不支持
getRemoteCertificates7272 未知 不支持1 未知50 不支持
iceTransport7272 未知 不支持1 未知50 不支持
onerror7272 未知 不支持1 未知50 不支持
onstatechange7272 未知 不支持1 未知50 不支持
state7272 未知 不支持1 未知50 不支持
statechange 事件7272 未知 不支持1 未知50 不支持

1. 参见 bug 1307996

2. 通过 transport 支持。

3. 通过 ondtlsstatechange 支持。

4. 通过 dtlsstatechange 支持。

相关链接