Start · Sprachen · JavaScript · Referenz · WebTransportBidirectionalStream

WebTransportBidirectionalStream

Schnittstelle

Repräsentiert einen bidirektionalen, zuverlässigen WebTransport-Stream mit einem <code>readable</code>- und einem <code>writable</code>-Ende für Daten in beide Richtungen.

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

Signatur

interface WebTransportBidirectionalStream

Beschreibung

Das Interface WebTransportBidirectionalStream gehört zur WebTransport API und steht für einen einzelnen bidirektionalen Stream innerhalb einer HTTP/3-WebTransport-Sitzung. Ein solcher Stream hat zwei Hälften: readable (ein WebTransportReceiveStream, also ein ReadableStream für eingehende Bytes) und writable (ein WebTransportSendStream, also ein WritableStream für ausgehende Bytes).

Die Übertragung ist zuverlässig und geordnet: Anders als bei Datagrammen (WebTransport.datagrams) kommen alle Bytes eines Streams vollständig und in der richtigen Reihenfolge an. Da jeder Stream unabhängig ist, blockiert ein verlorenes Paket in einem Stream die anderen nicht (kein Head-of-Line-Blocking wie bei WebSockets über TCP).

Man erhält Instanzen nicht über einen Konstruktor, sondern auf zwei Wegen:

  • Selbst geöffnet über await transport.createBidirectionalStream().
  • Vom Gegenüber (Server) geöffnet, empfangen über den ReadableStream transport.incomingBidirectionalStreams.

Typische Einsatzfälle sind Anfrage/Antwort-Protokolle (RPC), Spiele-Steuerbefehle oder Chat-Kanäle, bei denen jede logische Unterhaltung einen eigenen Stream bekommt. Das Interface ist in Fenstern und Web Workern verfügbar.

Parameter

Name Typ Default Beschreibung
$readable Pflicht WebTransportReceiveStream (ReadableStream<Uint8Array>) Schreibgeschützte Eigenschaft: Lesbares Ende des Streams für vom Gegenüber gesendete Bytes. Mit getReader() oder for await lesen.
$writable Pflicht WebTransportSendStream (WritableStream<Uint8Array>) Schreibgeschützte Eigenschaft: Beschreibbares Ende des Streams. Über getWriter() Daten als Uint8Array/ArrayBuffer senden; close() signalisiert das Ende (FIN).

Rückgabewert

Typ
WebTransportBidirectionalStream
Beschreibung
Wird von WebTransport.prototype.createBidirectionalStream() (als Promise) bzw. als Chunk von WebTransport.incomingBidirectionalStreams geliefert.

Beispiele

Stream öffnen, Anfrage senden und Antwort lesen

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

// Bidirektionalen Stream erzeugen
const stream = await transport.createBidirectionalStream();

// Anfrage schreiben
const writer = stream.writable.getWriter();
await writer.write(new TextEncoder().encode('PING'));
await writer.close(); // Senderichtung beenden (FIN)

// Antwort vollständig lesen
const decoder = new TextDecoder();
let antwort = '';
for await (const chunk of stream.readable) {
  antwort += decoder.decode(chunk, { stream: true });
}
antwort += decoder.decode();
console.log('Antwort:', antwort);
Antwort: PONG

Vom Server geöffnete Streams empfangen (Echo)

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

const handleStream = async ({ readable, writable }) => {
  // Alles Empfangene direkt zurücksenden
  await readable.pipeTo(writable);
  console.log('Stream beendet');
};

const reader = transport.incomingBidirectionalStreams.getReader();
while (true) {
  const { value: stream, done } = await reader.read();
  if (done) break;
  handleStream(stream).catch(err => console.error('Stream-Fehler:', err));
}
Stream beendet

Stream mit Fehlercode abbrechen und Fehler auswerten

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

const stream = await transport.createBidirectionalStream();
const writer = stream.writable.getWriter();

try {
  await writer.write(new Uint8Array([1, 2, 3]));
  // Senderichtung mit anwendungsspezifischem Code abbrechen (RESET_STREAM)
  await writer.abort(new WebTransportError({ message: 'Abbruch', streamErrorCode: 42 }));
  // Leserichtung ebenfalls verwerfen (STOP_SENDING)
  await stream.readable.cancel();
  console.log('Stream abgebrochen');
} catch (err) {
  if (err instanceof WebTransportError) {
    console.error(err.source, err.streamErrorCode);
  }
}
Stream abgebrochen

// Wichtig · Fallstricke

  • Kompatibilität: Chromium-Browser ab Version 97 und Firefox ab 114 unterstützen WebTransport; Safari hat (Stand 2024) noch keine Unterstützung. Vorher mit 'WebTransport' in globalThis prüfen und ggf. auf WebSockets zurückfallen.
  • Nur in sicheren Kontexten (HTTPS) verfügbar; der Server muss HTTP/3 mit WebTransport sprechen. Für Entwicklungszertifikate kann serverCertificateHashes im WebTransport-Konstruktor genutzt werden (nur kurzlebige ECDSA-Zertifikate).
  • Es gibt keinen öffentlichen Konstruktor – new WebTransportBidirectionalStream() wirft einen TypeError.
  • Ein Stream ist ein Byte-Strom, keine Nachrichtenfolge: write()-Aufrufe können beim Empfänger zu anderen Chunk-Grenzen zusammengefasst oder aufgeteilt werden. Für Nachrichten eigene Längenpräfixe oder Trennzeichen verwenden.
  • Jede Richtung wird unabhängig beendet: writable.close() schließt nur die Senderichtung; das Lesen bleibt möglich. Nicht geschlossene Writer/Reader halten Locks – vor pipeTo() keinen eigenen Reader/Writer anlegen.
  • Wird die Sitzung mit transport.close() beendet oder bricht die Verbindung ab, werden beide Hälften mit einem WebTransportError fehlerhaft abgeschlossen – Fehler immer abfangen.