Start · Sprachen · JavaScript · Referenz · WebTransportDatagramsWritable

WebTransportDatagramsWritable

Schnittstelle

Spezieller <code>WritableStream</code>, mit dem man ausgehende Datagramme über eine WebTransport-Verbindung sendet. Priorität und Gruppierung lassen sich über <code>sendOrder</code> und <code>sendGroup</code> festlegen.

seit JavaScript Eingeschränkt verfügbar: nur in Teilen aktueller C Kategorie: webapi

Signatur

interface WebTransportDatagramsWritable extends WritableStream

Beschreibung

WebTransportDatagramsWritable gehört zur WebTransport-API. Das Interface erweitert WritableStream. Jeder Aufruf von writer.write(chunk) mit einem Uint8Array (oder einer anderen BufferSource) sendet genau ein Datagramm über die HTTP/3-Verbindung (QUIC) zum Server.

Datagramme sind unzuverlässig und ungeordnet. Sie können verloren gehen, doppelt oder in anderer Reihenfolge ankommen. Dafür haben sie eine sehr geringe Latenz. Deshalb passen sie gut zu Daten, bei denen nur der neueste Stand zählt, zum Beispiel:

  • Spielerpositionen in Echtzeitspielen,
  • Sensor- und Telemetriewerte,
  • Steuerbefehle mit kurzer Lebensdauer.

Wenn jede Nachricht ankommen muss, nimmt man stattdessen Streams (createBidirectionalStream() bzw. createUnidirectionalStream()).

Instanzen entstehen über transport.datagrams.createWritable(options). Man kann mehrere solcher Streams anlegen und ihnen unterschiedliche Prioritäten geben. Dafür gibt es zwei Eigenschaften, die man auch nachträglich setzen kann:

  • sendOrder: Zahl für die Sendepriorität. Höhere Werte werden zuerst gesendet.
  • sendGroup: ordnet den Stream einer WebTransportSendGroup zu. Innerhalb einer Gruppe wird nach sendOrder priorisiert.

In älteren Implementierungen ist transport.datagrams.writable ein einfacher WritableStream ohne diese Eigenschaften.

Parameter

Name Typ Default Beschreibung
$options object {} Optionen für WebTransportDatagramDuplexStream.createWritable(options), womit Instanzen dieses Interfaces erzeugt werden.
$options.sendGroup WebTransportSendGroup | null null Sendegruppe, zu der der Stream gehört. Die Gruppe erzeugt man mit transport.createSendGroup(). Später lesbar und änderbar über die Eigenschaft sendGroup.
$options.sendOrder number 0 Sendepriorität. Höhere Werte werden bevorzugt gesendet. Später lesbar und änderbar über die Eigenschaft sendOrder.

Rückgabewert

Typ
WebTransportDatagramsWritable
Beschreibung
createWritable() gibt einen beschreibbaren Stream zurück. Mit getWriter() holt man sich einen WritableStreamDefaultWriter; jeder write()-Aufruf sendet ein Datagramm.

Beispiele

Stream anlegen und ein Datagramm senden

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

// Beschreibbaren Datagramm-Stream erzeugen
const writable = transport.datagrams.createWritable();
const writer = writable.getWriter();

const data = new TextEncoder().encode('ping');
await writer.write(data);
console.log('Datagramm gesendet, Größe:', data.byteLength);

writer.releaseLock();
Datagramm gesendet, Größe: 4

Echtzeit-Positionen mit hoher Priorität senden

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

// Positionen dringend, Chat-Hinweise weniger dringend
const positions = transport.datagrams.createWritable({ sendOrder: 10 });
const hints = transport.datagrams.createWritable({ sendOrder: 1 });

const posWriter = positions.getWriter();

const sendPosition = async (x, y) => {
  const buf = new Float32Array([x, y]);
  await posWriter.ready; // Gegendruck (Backpressure) beachten
  posWriter.write(new Uint8Array(buf.buffer));
};

await sendPosition(12.5, 7.25);
console.log(positions.sendOrder, hints.sendOrder);
10 1

Sendegruppe und Priorität nachträglich ändern

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

const group = transport.createSendGroup();
const writable = transport.datagrams.createWritable({ sendGroup: group });

// Priorität zur Laufzeit anheben
writable.sendOrder = 5;
console.log(writable.sendGroup === group, writable.sendOrder);
true 5

Maximale Datagrammgröße prüfen und Fehler behandeln

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

const max = transport.datagrams.maxDatagramSize;
const writer = transport.datagrams.createWritable().getWriter();

const payload = new Uint8Array(2000);
if (payload.byteLength > max) {
  console.warn(`Zu groß (${payload.byteLength} > ${max}), wird aufgeteilt`);
  for (let i = 0; i < payload.byteLength; i += max) {
    await writer.write(payload.subarray(i, i + max));
  }
} else {
  await writer.write(payload);
}

transport.closed.catch((err) => console.error('Verbindung beendet:', err));
Zu groß (2000 > 1200), wird aufgeteilt

// Wichtig · Fallstricke

  • Keine Zustellgarantie: Wenn write() erfüllt wird, heißt das nur, dass das Datagramm lokal angenommen wurde. Ob es ankommt, ist damit nicht gesagt. Datagramme können still verworfen werden, etwa wenn sie länger in der Warteschlange liegen als datagrams.outgoingMaxAge erlaubt.
  • Größenlimit: Ein Datagramm darf nicht größer sein als transport.datagrams.maxDatagramSize (oft etwa 1200 Byte, abhängig vom Pfad). Zu große Daten werden verworfen und nicht automatisch aufgeteilt. Das Aufteilen und Zusammensetzen muss die Anwendung selbst übernehmen.
  • Gegendruck (Backpressure): Vor dem Schreiben auf writer.ready warten. Sonst wächst die interne Warteschlange (outgoingHighWaterMark) und Daten veralten.
  • Kompatibilität: WebTransport gibt es nur im sicheren Kontext (HTTPS) und nur mit einem HTTP/3-Server. createWritable(), sendOrder und sendGroup sind neuer als die Basis-API. Ältere Browser bieten nur datagrams.writable als einfachen WritableStream. Safari unterstützt WebTransport bislang nicht. Deshalb vorher prüfen, ob die Funktion vorhanden ist, z. B. mit 'createWritable' in transport.datagrams.
  • Es kann immer nur ein Writer den Stream sperren. Mit releaseLock() gibt man ihn wieder frei. Wird die Verbindung geschlossen, schlagen alle weiteren write()-Aufrufe fehl.