Start · Sprachen · JavaScript · Referenz · WebTransportDatagramDuplexStream

WebTransportDatagramDuplexStream

Schnittstelle

Stellt über <code>WebTransport.datagrams</code> einen Duplex-Stream bereit, mit dem unzuverlässige, ungeordnete Datagramme zwischen Client und Server gesendet und empfangen werden.

seit JavaScript Chrome/Edge 97+, Firefox 114+, Safari: nicht unter Kategorie: webapi

Signatur

interface WebTransportDatagramDuplexStream

Beschreibung

Das Interface WebTransportDatagramDuplexStream gehört zur WebTransport API. Man erzeugt es nicht selbst, sondern bekommt es über die Eigenschaft WebTransport.datagrams einer bestehenden Verbindung. Es kombiniert einen ReadableStream (readable) für eingehende und einen WritableStream (writable) für ausgehende Datagramme. Beide transportieren Uint8Array-Blöcke.

Datagramme laufen über HTTP/3 bzw. QUIC und sind unzuverlässig: Pakete können verloren gehen, in anderer Reihenfolge ankommen und werden nicht erneut gesendet. Dafür fällt das Head-of-Line-Blocking weg und die Latenz ist minimal. Gut geeignet sind Echtzeit-Daten, bei denen nur der neueste Stand zählt, zum Beispiel Spielerpositionen in Online-Spielen, Telemetrie, Sensorwerte oder Audio- und Video-Frames mit geringer Latenz.

Über zusätzliche Eigenschaften lässt sich das Puffern steuern:

  • maxDatagramSize: größte Nutzlast pro Datagramm in Byte (nur lesbar)
  • incomingHighWaterMark / outgoingHighWaterMark: Puffergröße in Anzahl Datagrammen
  • incomingMaxAge / outgoingMaxAge: Höchstalter in Millisekunden, danach werden gepufferte Datagramme verworfen (null = kein Limit)

Brauchen Sie zuverlässige, geordnete Übertragung, nehmen Sie stattdessen createBidirectionalStream() oder createUnidirectionalStream().

Parameter

Name Typ Default Beschreibung
$readable ReadableStream<Uint8Array> Nur lesbar. Stream der vom Server empfangenen Datagramme.
$writable WritableStream<Uint8Array> Nur lesbar. Stream zum Senden von Datagrammen an den Server. In neueren Implementierungen kann es auch über createWritable() erzeugt werden.
$maxDatagramSize number Nur lesbar. Größte erlaubte Nutzlast pro Datagramm in Byte. Hängt von der Path-MTU ab, meist etwas über 1000 Byte.
$incomingHighWaterMark number implementierungsabhängig Größe des Eingangspuffers in Datagrammen, bevor eingehende Pakete verworfen werden.
$outgoingHighWaterMark number implementierungsabhängig Größe des Ausgangspuffers in Datagrammen; bestimmt den Gegendruck (Backpressure) beim Schreiben.
$incomingMaxAge number | null null Höchstalter eingehender Datagramme im Puffer in Millisekunden.
$outgoingMaxAge number | null null Höchstalter ausgehender Datagramme in Millisekunden. Ältere Pakete werden nicht mehr gesendet.

Rückgabewert

Typ
WebTransportDatagramDuplexStream
Beschreibung
Die Instanz erhalten Sie über transport.datagrams. Es gibt keinen öffentlichen Konstruktor.

Beispiele

Verbindung aufbauen und Datagramm senden

const transport = new WebTransport('https://example.com:4433/game');
await transport.ready;

// Duplex-Stream für Datagramme holen
const { datagrams } = transport;
console.log('Max. Größe:', datagrams.maxDatagramSize);

const writer = datagrams.writable.getWriter();
const payload = new TextEncoder().encode('ping');
await writer.write(payload);
writer.releaseLock();
Max. Größe: 1200

Eingehende Datagramme fortlaufend 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('Datagramm-Stream abgebrochen:', err);
}
Empfangen: {"temp":21.4}

Spielerposition mit Altersgrenze und Größenprüfung senden

const transport = new WebTransport('https://example.com:4433/game');
await transport.ready;

const dg = transport.datagrams;
// Veraltete Positionen nach 50 ms verwerfen
dg.outgoingMaxAge = 50;
dg.outgoingHighWaterMark = 10;

const writer = dg.writable.getWriter();

const sendPosition = async (x, y) => {
  const buf = new Float32Array([x, y]);
  const bytes = new Uint8Array(buf.buffer);
  if (bytes.byteLength > dg.maxDatagramSize) {
    throw new RangeError('Datagramm zu groß');
  }
  await writer.ready; // Backpressure beachten
  writer.write(bytes);
};

setInterval(() => sendPosition(Math.random() * 100, Math.random() * 100), 16);

// Wichtig · Fallstricke

  • Keine Zustellgarantie: Datagramme können verloren gehen, doppelt oder in anderer Reihenfolge ankommen. Wenn nötig, Sequenznummern selbst mitschicken und auf Anwendungsebene auswerten.
  • Größenlimit: Pakete über maxDatagramSize werden verworfen und nicht fragmentiert. Große Daten müssen Sie selbst aufteilen oder über Streams senden.
  • Nur ein Lock: getReader() bzw. getWriter() sperren den Stream. Rufen Sie releaseLock() auf, bevor anderer Code darauf zugreift.
  • Kompatibilität: Unterstützt ab Chromium 97 und Firefox 114. Safari unterstützt WebTransport noch nicht. Die API ist nur in sicheren Kontexten (HTTPS) verfügbar, der Server muss HTTP/3 mit WebTransport können. Prüfen Sie die Unterstützung mit 'WebTransport' in globalThis.
  • Die Eigenschaften incomingMaxAge, outgoingMaxAge und die HighWaterMarks sind je nach Browser unterschiedlich weit umgesetzt. Werte werden eventuell ignoriert.
  • Wird die Verbindung geschlossen (transport.close() oder Netzwerkfehler), brechen readable und writable mit einem Fehler ab. Lese-Schleifen deshalb in try/catch packen.