WebTransport
WebTransport — новый веб-API для двусторонней передачи данных поверх HTTP/3. Заменит WebSocket и WebRTC data channels в браузерах. Позволяет открывать множество независимых стримов и отправлять unreliable datagrams — то что WebSocket не умеет. Стандарт: RFC 9308, RFC 9297.
Зачем нужен ещё один транспорт
| WebSocket | WebRTC DataChannel | WebTransport | |
|---|---|---|---|
| Транспорт | TCP + TLS | UDP + DTLS + SCTP | UDP + TLS + QUIC |
| Head-of-line blocking | Есть (TCP) | Нет | Нет (QUIC-стримы) |
| Unreliable datagrams | Нет | Да | Да |
| Multiple streams | 1 канал | Много | Много |
| Setup latency | Средне (TCP+TLS+WS) | Долго (ICE, STUN, TURN) | Быстро (0-RTT QUIC) |
| Требует STUN/TURN | Нет | Да | Нет (клиент-сервер) |
| Настройка сервера | Легко | Сложно | Средне |
Модель
WebTransport — клиент-серверный, не P2P (в отличие от WebRTC). Три типа передачи:
- Bidirectional streams. Как TCP-канал, но их можно открыть много параллельно. Reliable, ordered.
- Unidirectional streams. Только в одну сторону. Клиент → сервер или сервер → клиент.
- Datagrams. Небольшие сообщения, unreliable, unordered. Аналог UDP.
Клиентский API
const wt = new WebTransport('https://example.com:4433/wt');
await wt.ready;
// Datagram (unreliable)
const writer = wt.datagrams.writable.getWriter();
await writer.write(new Uint8Array([1, 2, 3]));
const reader = wt.datagrams.readable.getReader();
const { value } = await reader.read();
// Bidirectional stream
const stream = await wt.createBidirectionalStream();
const w = stream.writable.getWriter();
await w.write(new TextEncoder().encode('hello'));
// Принять стрим от сервера
for await (const stream of wt.incomingBidirectionalStreams) {
const r = stream.readable.getReader();
const { value } = await r.read();
console.log(new TextDecoder().decode(value));
}
Как оно работает
WebTransport открывается через Extended CONNECT метод HTTP/3:
:method = CONNECT
:protocol = webtransport
:scheme = https
:authority = example.com
:path = /wt
Сервер отвечает 200, дальше это специальная HTTP-сессия внутри которой ходят QUIC-стримы и datagram'ы. RFC 9297 определяет как QUIC-стримы мапятся на WebTransport-стримы.
Требования
- HTTPS обязателен.
- Сертификат должен быть валиден по обычной цепочке (или serverCertificateHashes — можно указать конкретный хеш для self-signed).
- Сервер должен поддерживать HTTP/3.
serverCertificateHashes
Уникальная фича — можно подключиться к серверу с self-signed сертификатом, указав явно ожидаемый хеш:
const wt = new WebTransport('https://custom.example:4433/', {
serverCertificateHashes: [{
algorithm: 'sha-256',
value: new Uint8Array([...])
}]
});
Требования: сертификат ECDSA (не RSA), срок жизни ≤14 дней. Идея — для локальных/embedded устройств без публичного CA.
Реализации серверов
- aioquic (Python) — reference.
- quiche (Rust/Cloudflare) — используется в Cloudflare Workers, Wrangler.
- msquic (Microsoft, C++).
- go-quic — экспериментально.
- quic-go — с WebTransport-модулем.
Браузеры
- Chrome/Edge — с версии 97 (2022).
- Firefox — с 114 (2023).
- Safari — с 18 (2024).
Использование
Клубы применения: cloud-gaming (низкая latency), VoIP-клиенты, стриминг медиа, MMO-игры в браузере, IoT-контроль. Также предложен как транспорт для WebRTC 2.0.
WebTransport vs WebSocket over HTTP/3
Существует также WebSocket over HTTP/3 (RFC 9220) — обычный WebSocket, но по QUIC. Проще API, но всё ещё один канал с head-of-line. WebTransport — принципиально новый API с multiple streams и datagrams.