Start · Sprachen · JavaScript · Referenz · WebTransportSendStream

WebTransportSendStream

Schnittstelle

Ein spezialisierter <code>WritableStream</code> der WebTransport API, über den ausgehende Daten in unidirektionalen oder bidirektionalen WebTransport-Streams gesendet werden.

seit JavaScript Chrome/Edge 97+, Firefox 114+; Safari: eingeschrän Kategorie: webapi

Signatur

interface WebTransportSendStream extends WritableStream

Beschreibung

WebTransportSendStream ist die Sendeseite eines WebTransport-Streams über HTTP/3 (QUIC). Da das Interface von WritableStream erbt, schreibt man darauf wie auf jeden anderen Streams-API-Stream: mit getWriter() und writer.write() oder per readableStream.pipeTo(sendStream). Die geschriebenen Daten müssen Uint8Arrays bzw. andere BufferSource-Werte sein.

Einen Konstruktor gibt es nicht. Instanzen bekommt man über WebTransport.prototype.createUnidirectionalStream(), das direkt einen WebTransportSendStream zurückgibt, oder über WebTransport.prototype.createBidirectionalStream(). Im zweiten Fall steckt die Sendeseite in der Eigenschaft writable des zurückgegebenen WebTransportBidirectionalStream. Bidirektionale Streams, die der Server öffnet, kommen über transport.incomingBidirectionalStreams an.

Zusätzlich zu WritableStream bietet das Interface:

  • sendOrder (number | null, lesbar und schreibbar): die Sendepriorität. Streams mit höherem Wert werden bevorzugt übertragen. Bei null gibt es keine Priorität.
  • sendGroup (WebTransportSendGroup | null): ordnet den Stream einer Gruppe zu. Innerhalb der Gruppe wird dann nach sendOrder priorisiert. Wird noch nicht überall unterstützt.
  • getStats(): liefert ein Promise mit Statistiken zum Stream, etwa bytesWritten, bytesSent und bytesAcknowledged.

Sinnvoll sind Send-Streams immer dann, wenn Daten zuverlässig und in der richtigen Reihenfolge ankommen müssen, zum Beispiel Spielzustände, Chat-Nachrichten oder Datei-Uploads. Für verlustbehaftete Echtzeitdaten mit geringer Latenz sind dagegen Datagramme (transport.datagrams.writable) oft besser geeignet.

Parameter

Name Typ Default Beschreibung
$options.sendOrder number 0 Optionale Priorität, die an createUnidirectionalStream(options) oder createBidirectionalStream(options) übergeben wird. Landet in sendStream.sendOrder. Höhere Werte werden zuerst gesendet.
$options.sendGroup WebTransportSendGroup | null null Optionale Sendegruppe, erzeugt mit transport.createSendGroup(). Priorisiert wird dann innerhalb der Gruppe.
$options.waitUntilAvailable boolean false Bei true wartet das Erzeugen des Streams, bis das Stream-Limit des Servers wieder einen neuen Stream zulässt, statt sofort mit einem Fehler abzubrechen.

Rückgabewert

Typ
WebTransportSendStream
Beschreibung
Instanzen entstehen über await transport.createUnidirectionalStream() oder (await transport.createBidirectionalStream()).writable. getStats() gibt Promise<WebTransportSendStreamStats> zurück.

Beispiele

Unidirektionalen Stream öffnen und Text senden

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

// createUnidirectionalStream() liefert direkt einen WebTransportSendStream
const stream = await transport.createUnidirectionalStream();
console.log(stream instanceof WritableStream);

const writer = stream.getWriter();
const encoder = new TextEncoder();

await writer.write(encoder.encode('Hallo Server!'));
await writer.close(); // FIN senden: Stream sauber beenden
console.log('Nachricht gesendet');
true Nachricht gesendet

Bidirektionaler Stream: Anfrage senden, Antwort lesen

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

const { readable, writable } = await transport.createBidirectionalStream();

// writable ist ein WebTransportSendStream
const writer = writable.getWriter();
await writer.write(new TextEncoder().encode(JSON.stringify({ cmd: 'ping' })));
await writer.close();

// Antwort vom Server vollständig einlesen
const text = await new Response(readable).text();
console.log('Antwort:', text);
Antwort: {"cmd":"pong"}

Priorität per sendOrder setzen und Statistik abfragen

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

// Wichtiger Steuer-Stream mit hoher Priorität
const control = await transport.createUnidirectionalStream({ sendOrder: 100 });
// Großer Asset-Upload mit niedriger Priorität
const upload = await transport.createUnidirectionalStream({ sendOrder: 1 });

console.log(control.sendOrder, upload.sendOrder);

// Priorität lässt sich auch nachträglich ändern
upload.sendOrder = 10;

const writer = upload.getWriter();
await writer.write(new Uint8Array(64 * 1024));

const stats = await upload.getStats();
console.log('geschrieben:', stats.bytesWritten, 'gesendet:', stats.bytesSent);
100 1 geschrieben: 65536 gesendet: 65536

Datei per pipeTo hochladen und bei Fehler abbrechen

const uploadFile = async (transport, file) => {
  const sendStream = await transport.createUnidirectionalStream();
  try {
    // File.stream() liefert Uint8Array-Chunks, der Gegendruck wird automatisch berücksichtigt
    await file.stream().pipeTo(sendStream);
    console.log(`${file.name} hochgeladen`);
  } catch (err) {
    // pipeTo bricht den Stream bei Fehlern standardmäßig ab (RESET_STREAM)
    console.error('Upload fehlgeschlagen:', err);
  }
};

const input = document.querySelector('input[type=file]');
input.addEventListener('change', async () => {
  const transport = new WebTransport('https://example.com:4433/upload');
  await transport.ready;
  await uploadFile(transport, input.files[0]);
});
bericht.pdf hochgeladen