RTCQuicTransport 即将在您附近的源试用 (Chrome 73)

图片版本

RTCQuicTransport 是一种新的网络平台 API,它允许使用 QUIC 协议与远程对等方交换任意数据。它适用于点对点用例,因此可与独立的 RTCIceTransport API 搭配使用,以通过 ICE 建立点对点连接。数据可靠且有序地传输(如需详细了解无序和不可靠的传送,请参阅下文的部分)。由于它是一种通用的双向数据传输,因此可用于游戏、文件传输、媒体传输、消息传递等。

原因何在?

强大的低级别数据传输 API 可让应用(如实时通信)在网络上执行新操作。您可以在此 API 的基础上进行构建,创建自己的解决方案,突破点对点连接所能实现的限制,例如解锁自定义比特率分配旋钮。将来,通过进一步支持编码媒体,您甚至可以通过低级控件构建自己的视频通信应用。WebRTC NV 的努力朝向较低级别的 API 方向,及早进行此类测试非常有价值。

为何要使用 QUIC?

QUIC 协议适用于实时通信。它基于 UDP 构建,内置加密和拥塞控制,并且可以在没有行头阻塞的情况下进行多路复用。RTCQuicTransport 提供的功能与 RTCDataChannel API 非常相似,但使用 QUIC(而不是 SCTP)作为其传输协议。由于 RTCQuicTransport 是一个独立的 API,因此它没有 RTCPeerConnection API(包括实时媒体堆栈)的开销。

如何实现?

常规 API 概览

该 API 有 3 个主要抽象化:RTCIceTransportRTCQuicTransportRTCQuicStream

显示 API 架构的 RTCQuicTransport 图

RTCIceTransport

ICE 是一种通过互联网建立点对点连接的协议,现已在 WebRTC 中使用。此对象提供了一个独立的 API 来建立 ICE 连接。它用作 QUIC 连接的数据包传输,RTCQuicTransport 会在其构造函数中接受它。

RTCQuicTransport

表示 QUIC 连接。它用于建立 QUIC 连接和创建 QUIC 流。它还会显示 QUIC 连接级别的相关统计信息。

RTCQuicStream

用于从远程端读取和写入数据。数据流可靠且有序传输数据。可以通过同一 RTCQuicTransport 创建多个数据流,数据写入数据流后,它会在远程传输上触发“onquicstream”事件。数据流提供了一种区分同一 QUIC 连接上的不同数据的方法。常见示例包括跨单独的流发送单独的文件、跨不同流发送小块的数据,或者在单独的流之间发送不同类型的媒体。RTCQuicStream 是轻量级的,通过 QUIC 连接进行多路复用,并且不会导致行首阻塞其他 RTCQuicStream

连接设置

以下是设置点对点 QUIC 连接的示例。与 RTCPeerConnection 一样,RTCQuicTransport API 需要使用安全信号通道来协商连接的参数,包括其安全参数。RTCIceTransport 会协商其 ICE 参数(ufrag 和密码)以及 RTCIceCandidate

显示 API 架构的 RTCQuicTransport 图

客户观点:

const iceTransport = new RTCIceTransport();
const quicTransport = new RTCQuicTransport(iceTransport);
// Signal parameters, key and candidates.
signalingChannel.send({
  iceParams: iceTransport.getLocalParameters(),
  quicKey: quicTransport.getKey(),
});
iceTransport.onicecandidate = e => {
  if (e.candidate) {
    signalingChannel.send({candidate: e.candidate});
  }
};

// When remote parameters are signaled, start connection.
signalingChannel.onMessage = async ({iceParams, candidate}) => {
  if (iceParams) {
    iceTransport.start(iceParams);
    quicTransport.connect();
  } else if (candidate) {
    iceTransport.addRemoteCandidate(candidate);
  }
};

服务器角度:

const iceTransport = new RTCIceTransport();
const quicTransport = new RTCQuicTransport(iceTransport);
// Signal parameters, key and candidates.
signalingChannel.send({
  iceParams: iceTransport.getLocalParameters(),
});
iceTransport.onicecandidate = e => {
  if (e.candidate) {
    signalingChannel.send({candidate: e.candidate});
  }
};

// When remote parameters are signaled, start connection.
signalingChannel.onMessage = async ({iceParams, quicKey, candidate}) => {
  if (iceParams && quicKey) {
    iceTransport.start(iceParams);
    quicTransport.listen(quicKey);
  } else if (candidate) {
    iceTransport.addRemoteCandidate(candidate);
  }
};

Data Transfer

可以使用 RTCQuicStream API 实现数据传输:

RTCQuicStreamReadResult readInto(Uint8Array data);
void write(RTCQuicStreamWriteParameters data);
Promise<void> waitForWriteBufferedAmountBelow(unsigned long amount);
Promise<void> waitForReadable(unsigned long amount);

正在缓冲

waitFor* 方法返回的 promise 允许在 JavaScript 繁忙时缓冲数据。当接收端的读取缓冲区变满时,系统会向发送端应用背压。发送端有一个写入缓冲区,在应用背压后该缓冲区会填满,因此写入端还有一个 waitForWriteBufferedAmountBelow 方法,可允许在缓冲区中等待写入空间。如需详细了解如何写入/读取数据,请参阅其他开发者文档

无序/不可靠的配送

虽然 RTCQuicStream 仅支持可靠地按顺序发送数据,但可以通过其他方式实现不可靠/无序的传送。对于无序传送,可以在单独的数据流中发送小块的数据,因为数据流之间的数据不排序。对于不可靠的传送,可以发送小块数据,并将完成设置为 true,然后在超时后对数据流调用 reset()。超时时间应取决于在丢弃数据之前所需的重新传输次数。

时间

源试用将从 Chrome 73 版本开始,并一直持续到 M75 版本(含)版本。之后,源试用将结束。我们将根据反馈和兴趣进行适当更改,并推出此 API、继续通过此 API 进行新的源试用,或者停用此 API。

位置?

所有平台(iOS 除外)中的 Chrome 浏览器。

还有什么?

反馈

源试用的主要目标之一是获取开发者的反馈。我们希望了解:

  • 此 API 可为您实现什么用途?
  • 与其他数据传输 API(WebSocket 或 WebRTC 的 RTCDataChannel)相比,此 API 如何改进?它还可以如何改进?
  • 性能
  • API 工效学设计

注册源试用

  1. 为您的源请求令牌
  2. 将令牌添加到您的网页时,可通过以下两种方式在来源中的任何网页上提供此令牌:
    • origin-trial <meta> 标记添加到任意页面的标头中。例如,该文件可能如下所示:<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
    • 如果您能够配置服务器,还可以使用 Origin-Trial HTTP 标头在网页上提供令牌。生成的响应标头应如下所示:Origin-Trial: TOKEN_GOES_HERE

网络规范

规范草稿在源试用中已比 API 更靠前,包括:

  • 单向信息流,与 WHATWG 信息流更接近
  • 停用重新传输
  • (即将推出)数据图

我们有兴趣实现完整规范及更多内容(包括 WHATWG 流支持),但希望先收到您的反馈!

安全性

QUIC 握手的安全性是通过使用预共享密钥建立加密的点对点 QUIC 连接来实现的。此密钥需要通过安全的带外信道发送信号,并且保证机密性和完整性。请注意,键将向 JavaScript 公开。

主动攻击

DTLS-SRTP 只需要使用完整性来发送证书指纹,而发送预共享密钥信号需要完整性和机密性。如果 PSK 被破解(比如被信道信道中的服务器入侵),活跃的攻击者可能会针对 QUIC 握手发起中间人攻击。

当前状态

步骤 状态
1. 创建铺垫消息 完成
**2a. RTCQuicTransport 规范 ** **进行中**
**2b. RTCIceTransport 规范 ** **进行中**
**3. 收集反馈并不断改进设计** **进行中**
4. 源试用 从 Chrome 73 开始!
5. 发布 尚未开始

实用链接