Signatur
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. Beinullgibt es keine Priorität.sendGroup(WebTransportSendGroup | null): ordnet den Stream einer Gruppe zu. Innerhalb der Gruppe wird dann nachsendOrderpriorisiert. Wird noch nicht überall unterstützt.getStats(): liefert einPromisemit Statistiken zum Stream, etwabytesWritten,bytesSentundbytesAcknowledged.
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
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');
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);
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);
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]);
});