Skip to content

WebTransport Protocol

WebTransport is a next-generation web transport technology based on the QUIC protocol (HTTP/3). Compared to WebSocket, it offers lower latency, native multiplexing, and head-of-line blocking elimination, making it the future-oriented web streaming transport solution.

PropertyValue
Default Port4433
Transport LayerQUIC (HTTP/3)
Publish✅ Supported
Subscribe✅ Supported
Latency< 500ms
Feature Flagwebtransport
Cargo.toml
[features]
webtransport = ["dep:plugin-webtransport"]
webtransport:
enable: true
listen_addr: "0.0.0.0:4433"
cert_file: ""
key_file: ""
max_streams: 100
enable_datagrams: true
max_datagram_size: 65535
idle_timeout: 30
allowed_origins: []
OptionTypeDefaultDescription
enablebooltrueWhether to enable the plugin
listen_addrstring"0.0.0.0:4433"Listen address
cert_filestring""TLS certificate file path
key_filestring""TLS private key file path
max_streamsu32100Maximum concurrent streams per connection
enable_datagramsbooltrueEnable Datagram support
max_datagram_sizeusize65535Maximum Datagram size
idle_timeoutu6430Idle timeout (seconds)
allowed_originsVec[]Allowed cross-origin sources

WebTransport is based on QUIC and requires TLS encrypted transport.

Using self-signed certificates (development):

If cert_file and key_file are not configured, the plugin will automatically generate a self-signed certificate.

Using production certificates:

webtransport:
cert_file: "/etc/ssl/certs/server.crt"
key_file: "/etc/ssl/private/server.key"

Certificates issued by CAs such as Let’s Encrypt are supported.

WebTransport is a relatively new Web API. Current support status:

BrowserSupported Version
Chrome97+
Edge97+
Firefox114+
SafariNot supported (as of 2025)
Opera83+
async function publish(streamPath) {
const url = `https://localhost:4433/publish/${streamPath}`;
const transport = new WebTransport(url);
await transport.ready;
console.log('WebTransport connection established');
// Get camera
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
});
// Send media data via bidirectional stream
const bidiStream = await transport.createBidirectionalStream();
const writer = bidiStream.writable.getWriter();
// Send media data...
// Specific encoding and encapsulation logic depends on the application-layer protocol
transport.closed.then(() => {
console.log('WebTransport connection closed');
});
}
publish('live/test');
async function subscribe(streamPath) {
const url = `https://localhost:4433/subscribe/${streamPath}`;
const transport = new WebTransport(url);
await transport.ready;
console.log('WebTransport connection established');
// Read data pushed by the server
const reader = transport.incomingBidirectionalStreams.getReader();
while (true) {
const { value: stream, done } = await reader.read();
if (done) break;
// Process received media data
const streamReader = stream.readable.getReader();
while (true) {
const { value, done } = await streamReader.read();
if (done) break;
// Decode and render...
}
}
}
subscribe('live/test');

Datagram mode is suitable for scenarios that demand extreme real-time performance and can tolerate minor packet loss:

const transport = new WebTransport(url);
await transport.ready;
// Send Datagram
const writer = transport.datagrams.writable.getWriter();
await writer.write(new Uint8Array([/* media data */]));
// Receive Datagram
const reader = transport.datagrams.readable.getReader();
const { value } = await reader.read();
FeatureWebTransportWebRTC
Underlying ProtocolQUIC (HTTP/3)ICE/DTLS/SRTP
Connection SetupSimple (HTTP upgrade)Complex (ICE + SDP exchange)
NAT TraversalNot required (HTTP-like)Requires STUN/TURN
MultiplexingNative supportNot supported
Ordered/UnorderedBoth supportedPartially supported
Server RequirementsTLS certificate requiredSTUN/TURN server required
Browser SupportNewerMature
  • Existing HTTPS infrastructure: Prefer WebTransport
  • Need P2P communication: Choose WebRTC
  • Need maximum browser compatibility: Choose WebRTC
  • Pursuing architectural simplicity: Choose WebTransport

Streams published via WebTransport can be played back through other protocols:

Terminal window
# Subscribe via RTMP
ffplay rtmp://localhost:1935/live/test
# Subscribe via HTTP-FLV
ffplay http://localhost:8080/flv/live/test.flv
# Subscribe via HLS
ffplay http://localhost:8080/hls/live/test/index.m3u8