Web Transport API
WebTransport is a modern API that provides low-latency, bidirectional, client-server messaging. It is built on top of HTTP/3 (and thus QUIC), offering a powerful alternative to WebSockets.
1. Why WebTransport?
While WebSockets are great for real-time communication, they are based on TCP. This means they suffer from "Head-of-Line Blocking": if one packet is lost, all subsequent packets must wait until it is retransmitted.
WebTransport, being based on QUIC, solves this. It supports:
- Datagrams: Unreliable, out-of-order delivery (like UDP). Great for gaming or live streaming where speed > perfect accuracy.
- Streams: Reliable, ordered delivery (like TCP), but multiple streams within a single connection are independent. If one stream blocks, others continue.
2. Connecting
To connect, you create a WebTransport instance with a URL (must be HTTPS).
const url = 'https://example.com:4433/webtransport';
const transport = new WebTransport(url);
// Wait for connection to be ready
try {
await transport.ready;
console.log('Connected to WebTransport!');
} catch (e) {
console.error('Connection failed:', e);
}
// Handle closure
transport.closed.then(() => {
console.log('Connection closed normally');
}).catch((error) => {
console.error('Connection closed abruptly:', error);
});
3. Sending Datagrams (Unreliable)
Datagrams are "fire and forget". They are fast but might arrive out of order or not at all.
const writer = transport.datagrams.writable.getWriter();
const data = new Uint8Array([65, 66, 67]);
writer.write(data);
writer.releaseLock();
4. Receiving Datagrams
const reader = transport.datagrams.readable.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log('Received datagram:', value);
}
5. Streams (Reliable)
WebTransport supports both unidirectional (one-way) and bidirectional (two-way) streams. These use the standard Streams API.
Creating a Bidirectional Stream
const stream = await transport.createBidirectionalStream();
// stream.readable (ReadableStream)
// stream.writable (WritableStream)
const writer = stream.writable.getWriter();
await writer.write(new TextEncoder().encode("Hello Server"));
writer.close();
Receiving Streams
You listen for incoming streams from the server.
const reader = transport.incomingBidirectionalStreams.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
const stream = value;
// Handle the new stream...
// readDataFromStream(stream.readable);
}
6. WebTransport vs. WebSockets
| Feature | WebSockets | WebTransport |
|---|---|---|
| Protocol | TCP | QUIC (HTTP/3) |
| Head-of-Line Blocking | Yes (Global) | No (Per stream/datagram) |
| Unreliable Data | No | Yes (Datagrams) |
| Multiple Streams | No (Single stream) | Yes (Lightweight streams) |
| Use Case | Chat, simple real-time | Gaming, Live Streaming, heavy real-time |
programming/javascript/vanilla/javascript programming/javascript/vanilla/websockets programming/javascript/vanilla/streams-api