Start · Sprachen · JavaScript · Referenz · WebTransportBidirectionalStream.readable

WebTransportBidirectionalStream.readable

Eigenschaft

Schreibgeschützte Eigenschaft, die den lesbaren Teil eines bidirektionalen WebTransport-Streams als <code>WebTransportReceiveStream</code> liefert.

seit JavaScript Chrome/Edge 97+, Firefox 114+, Safari 26.4+; nur i Kategorie: webapi

Signatur

WebTransportBidirectionalStream.readable

Beschreibung

Ein WebTransportBidirectionalStream besteht aus zwei Hälften: readable für eingehende und writable für ausgehende Daten. Die Eigenschaft readable gibt eine Instanz von WebTransportReceiveStream zurück. Diese Klasse erbt von ReadableStream und liefert Daten als Uint8Array-Blöcke, die über HTTP/3 (QUIC) zuverlässig und in der richtigen Reihenfolge ankommen.

Einen bidirektionalen Stream bekommst du auf zwei Wegen. Entweder öffnest du ihn selbst mit WebTransport.prototype.createBidirectionalStream(), oder der Server öffnet ihn und du nimmst ihn über WebTransport.incomingBidirectionalStreams entgegen. In beiden Fällen liest du die Antworten der Gegenseite über readable. Das passt zum Beispiel für Anfrage-Antwort-Muster, RPC-Aufrufe oder Chat-Kanäle, bei denen keine Nachricht verloren gehen darf.

Weil es ein gewöhnlicher ReadableStream ist, stehen alle Werkzeuge der Streams-API bereit: getReader(), for await...of, pipeTo(), pipeThrough() (etwa mit TextDecoderStream) und cancel(). Zusätzlich gibt es getStats() für Statistiken auf Transportebene.

Rückgabewert

Typ
WebTransportReceiveStream
Beschreibung
Ein ReadableStream, genauer ein WebTransportReceiveStream, der die empfangenen Bytes als Uint8Array-Blöcke liefert. Die Eigenschaft gibt bei jedem Zugriff dasselbe Objekt zurück.

Beispiele

Anfrage senden und Antwort über readable lesen

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

const stream = await transport.createBidirectionalStream();

// Anfrage schreiben
const writer = stream.writable.getWriter();
await writer.write(new TextEncoder().encode('Hallo Server'));
await writer.close();

// Antwort lesen
const reader = stream.readable.getReader();
const decoder = new TextDecoder();
let antwort = '';
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  antwort += decoder.decode(value, { stream: true });
}
antwort += decoder.decode();
console.log('Antwort:', antwort);
Antwort: Hallo Server

Vom Server geöffnete Streams mit for await...of verarbeiten

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

const handleStream = async (bidi) => {
  const textStream = bidi.readable.pipeThrough(new TextDecoderStream());
  for await (const chunk of textStream) {
    console.log('Empfangen:', chunk);
  }
  console.log('Stream beendet');
};

for await (const bidi of transport.incomingBidirectionalStreams) {
  handleStream(bidi); // bewusst nicht awaiten, damit mehrere Streams parallel laufen
}
Empfangen: Willkommen im Chat Stream beendet

Lesen per Timeout abbrechen und Fehler behandeln

const transport = new WebTransport('https://example.com:4433/data');
await transport.ready;
const { readable, writable } = await transport.createBidirectionalStream();

const writer = writable.getWriter();
await writer.write(new Uint8Array([1, 2, 3]));
await writer.close();

const timer = setTimeout(() => readable.cancel('Timeout'), 5000);
try {
  let bytes = 0;
  for await (const chunk of readable) {
    bytes += chunk.byteLength;
  }
  console.log(`Empfangen: ${bytes} Bytes`);
} catch (err) {
  // WebTransportError, z. B. wenn der Server den Stream zurücksetzt
  console.error('Lesefehler:', err.name, err.streamErrorCode);
} finally {
  clearTimeout(timer);
}
Empfangen: 3 Bytes

// Wichtig · Fallstricke

  • Kompatibilität: WebTransport gibt es in Chromium-Browsern (ab 97), Firefox (ab 114) und Safari (ab 26.4). Auf älteren Safari-Versionen fehlt es. Prüfe die Unterstützung vorher mit 'WebTransport' in globalThis. Die API funktioniert nur in sicheren Kontexten (HTTPS) und braucht einen Server, der HTTP/3 mit WebTransport unterstützt.
  • Lock: getReader() sperrt den Stream. Ein zweiter Aufruf, pipeTo() oder for await wirft dann einen TypeError, bis du reader.releaseLock() aufrufst.
  • Nachrichtengrenzen: Die Blöcke entsprechen nicht zwingend den einzelnen write()-Aufrufen der Gegenseite. Ein Datenstrom kann zerteilt oder zusammengefasst ankommen. Lege deshalb eigene Nachrichtengrenzen fest, zum Beispiel mit einem Längenpräfix oder Trennzeichen.
  • Fehler: Setzt die Gegenseite den Stream zurück (RESET_STREAM) oder bricht die Verbindung ab, wird read() mit einem WebTransportError abgelehnt. Den Anwendungs-Fehlercode findest du in streamErrorCode.
  • Abbrechen: readable.cancel() schickt der Gegenseite STOP_SENDING. Die writable-Hälfte bleibt davon unberührt. Du musst sie selbst mit close() oder abort() beenden.
  • Parallele Streams: Arbeite eingehende Streams nicht nacheinander mit await in der äußeren Schleife ab. Sonst blockiert ein lange laufender Stream alle folgenden.