本文初步了解下 WebTransport,受条件限制未进行实战内容,后续有机会进行实战内容的补充。
WebTransport 是一种使用 HTTP/3 协议作为双向传输的 Web API。它适用于 Web 客户端和 HTTP/3 服务器之间的双向通信。
HTTP/3
HTTP/3是一种新的网络协议,也被称为QUIC(Quick UDP Internet Connections)。它是基于UDP协议而不是TCP协议的,旨在提供更快、更安全和更可靠的互联网连接。
相比于HTTP/2,HTTP/3有以下几个主要特点:
更好的拥塞控制:QUIC内置了自己的拥塞控制机制,能够更好地适应网络状况变化。它可以通过动态调整传输速率来避免网络拥塞,并提供更稳定和可靠的数据传输。
更强大的安全性:QUIC默认使用TLS 1.3进行加密通信,并且在握手过程中就完成了身份验证。这意味着HTTPS将成为默认选项,并且所有数据都会得到保护。
兼容性:虽然HTTP/3基于UDP协议,但它仍然能够与现有基础设施兼容。例如,在客户端无法直接访问服务器时,可以通过代理服务器进行中转。
更低的延迟:由于使用了UDP协议,HTTP/3可以减少握手时间和连接建立时间,并且支持多路复用技术,在一个连接上同时发送多个请求和响应。这样可以显著降低延迟。
HTTP/3 的常用场景包括:
视频流媒体:HTTP/3 支持多路复用和 0-RTT 握手等功能,这对于实时视频流传输非常有利。它可以减少缓冲时间,并提供更稳定的视频播放体验,在云游戏等场景是一张王牌。
移动应用程序:移动设备通常面临不稳定的网络连接,而 HTTP/3 的抗干扰能力较强,可以在恶劣网络条件下保持良好的性能。因此,在移动应用中采用 HTTP/3 可以提供更好的用户体验。
物联网(IoT)应用程序:物联网设备通常具有资源受限、带宽受限和电池寿命短等特点。由于 HTTP/3 使用了 QUIC 协议作为底层传输协议,其轻量级和低功耗优势使得它成为适合物联网场景的选择。
检测网站对 HTTP/3 支持的工具:http3check
语法 API
截止目前(2024-01-04)WebTransport 仍然是一个是实验性API,并且需要在HTTPS环境下使用,浏览器兼容性如下
通过构造函数WebTransport(url[, options])
创建一个对象实例:
- url:一个支持HTTP/3的服务器地址;
- options:webtransport的配置对象
- allowPooling:是否允许和其他HTTP/3会话共享池共享网络连接;
- congestionControl:此连接发送数据时使用的拥塞控制算法应针对吞吐量或低延迟进行调整,default、 throughput和 low-latency;
- requireUnreliable:如果无法建立HTTP/3连接,则拒绝通过HTTP/2建立连接,默认为 false;
- serverCertificateHashes:一个对象数组,每个对象定义服务器证书的哈希值以及用于生成它的算法的名称
- algorithm:算法名称;
- value:证书Hash值。
const transport = new WebTransport(url, {
serverCertificateHashes: [
{
algorithm: "RSA",
value: "76DFA3DCBE1ACC7E05FC5037464FBCB79DAABEE3"
}
]
})
此时获取到了webTransport对象实例,实例常用属性有:
- ready:当webtransport可用时返回一个resolved Promise;
- closed:当webtransport关闭时返回一个resolved Promise;
- datagrams:双向数据报Stream,WebTransportDatagramsDuplexStream对象;
- congestionControl:拥塞控制算法的值;
- incomingBidirectionalStreams:从服务器打开的一个或多个双向流(readable、writable);
- incomingUnidirectionalStreams:从服务器打开的一个或多个单向流(readable)
- reliability:表示连接是否仅支持可靠传输。
async function receiveBidirectional() {
const bds = transport.incomingBidirectionalStreams;
const reader = bds.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
await readData(value.readable);
await writeData(value.writable);
}
}
async function readData(readable) {
const reader = readable.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) {
break;
}
console.log(value); // Uint8Array.
}
}
async function writeData(writable) {
const writer = writable.getWriter();
const data1 = new Uint8Array([65, 66, 67]);
const data2 = new Uint8Array([68, 69, 70]);
writer.write(data1);
writer.write(data2);
}
对浏览器中的Stream API不熟悉可以看下之前的笔记。
另外对象实例上的方法如下:
- close({coseCode: number, reason: string}):关闭连接,可以在关闭时传递原因;
- getStats():异步返回一个包含HTTP/3连接统计信息的对象;
- createBidirectionalStream({sendOrder: number}):创建双向流;
- createUnidirectionalStream({sendOrder: number}):创建单向流。
async function setUpBidirectional() {
const stream = await transport.createBidirectionalStream({
sendOrder: 99999,
});
const readable = stream.readable;
const writable = stream.writable;
}