Signatur
Beschreibung
Die Eigenschaft datagrams einer WebTransport-Instanz gibt ein WebTransportDatagramDuplexStream-Objekt zurück. Es enthält einen readable-Stream (ReadableStream) zum Empfangen und einen writable-Stream (WritableStream) zum Senden von Datagrammen. Jedes Datagramm ist ein Uint8Array.
Datagramme laufen über HTTP/3 bzw. QUIC und sind unzuverlässig: Ihre Zustellung ist nicht garantiert, sie können in anderer Reihenfolge eintreffen und es gibt keine Neuübertragung. Dadurch ist die Latenz sehr gering. Deshalb eignen sie sich für Daten, bei denen nur der neueste Zustand zählt, z. B. Spielerpositionen in Echtzeitspielen, Telemetrie, Sensorwerte oder Live-Medien-Metadaten. Wenn die Zustellung garantiert sein muss, nimmst du stattdessen bidirektionale oder unidirektionale Streams (createBidirectionalStream(), createUnidirectionalStream()).
Zusätzlich hat der Duplex-Stream Eigenschaften wie maxDatagramSize (die größte Nutzlast, die sich senden lässt), incomingHighWaterMark/outgoingHighWaterMark (Größe der Puffer) sowie incomingMaxAge/outgoingMaxAge (nach wie vielen Millisekunden veraltete Datagramme verworfen werden).
Rückgabewert
readable (ReadableStream<Uint8Array>) und writable (WritableStream<Uint8Array>) sowie Einstellungen wie maxDatagramSize. Für eine Verbindung wird immer dieselbe Instanz zurückgegeben.Beispiele
Verbindung aufbauen und ein Datagramm senden
const transport = new WebTransport('https://example.com:4433/game');
await transport.ready;
const writer = transport.datagrams.writable.getWriter();
const payload = new TextEncoder().encode(JSON.stringify({ x: 120, y: 48 }));
if (payload.byteLength <= transport.datagrams.maxDatagramSize) {
await writer.write(payload);
console.log('Datagramm gesendet:', payload.byteLength, 'Bytes');
}
writer.releaseLock();
Eingehende Datagramme in einer Schleife lesen
const transport = new WebTransport('https://example.com:4433/telemetry');
await transport.ready;
const reader = transport.datagrams.readable.getReader();
const decoder = new TextDecoder();
try {
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log('Empfangen:', decoder.decode(value));
}
} catch (err) {
console.error('Lesen abgebrochen:', err);
}
Positions-Updates regelmäßig senden, veraltete Daten verwerfen
const transport = new WebTransport('https://example.com:4433/game');
await transport.ready;
const { datagrams } = transport;
// Ausgehende Datagramme verwerfen, die älter als 100 ms sind
datagrams.outgoingMaxAge = 100;
const writer = datagrams.writable.getWriter();
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
const timer = setInterval(async () => {
view.setFloat32(0, Math.random() * 800);
view.setFloat32(4, Math.random() * 600);
await writer.ready; // Gegendruck (Backpressure) beachten
writer.write(new Uint8Array(buffer.slice(0)));
}, 50);
transport.closed.finally(() => clearInterval(timer));
// Wichtig · Fallstricke
- Keine Zustellgarantie: Datagramme können ohne Fehlermeldung verloren gehen, doppelt oder in anderer Reihenfolge ankommen. Reihenfolge und Duplikate musst du selbst erkennen, z. B. mit Sequenznummern.
- Größenlimit: Datagramme, die größer als
maxDatagramSizesind (typisch etwa 1200 Bytes), werden verworfen. Große Daten musst du selbst aufteilen oder über Streams schicken. - Stream-Sperre:
getWriter()undgetReader()sperren den jeweiligen Stream. RufereleaseLock()auf, bevor ein anderer Teil des Codes darauf zugreift. - Auf
readywarten: Vor dem Senden mussawait transport.readyabgeschlossen sein. Wird die Verbindung geschlossen, liefern die Streams Fehler bzw.done: true. - Kompatibilität: Funktioniert nur in sicheren Kontexten (HTTPS) und braucht einen HTTP/3-Server mit WebTransport-Unterstützung. Unterstützt ab Chromium 97, Firefox 114 und Safari 26.4. Ältere Safari-Versionen haben keine WebTransport-Unterstützung, daher solltest du die Unterstützung prüfen (
'WebTransport' in globalThis) und eine Ausweichlösung bereithalten, z. B. WebSocket. - Die Eigenschaften
incomingMaxAge,outgoingMaxAgeund die High-Water-Marks werden noch nicht überall gleich unterstützt.