Start · Sprachen · JavaScript · Referenz · new WebSocketStream()

new WebSocketStream()

Methode

Erstellt eine neue <code>WebSocketStream</code>-Instanz und baut eine WebSocket-Verbindung auf, deren Daten über <code>ReadableStream</code> und <code>WritableStream</code> fließen.

seit JavaScript Experimentell: Chromium 124+ (Chrome, Edge, Opera) Kategorie: webapi

Signatur

new WebSocketStream(url, options)

Beschreibung

Der Konstruktor WebSocketStream() öffnet eine WebSocket-Verbindung zur angegebenen URL. Anders als beim klassischen WebSocket gibt es keine Ereignisse wie onmessage: Die Verbindung wird über Promises und die Streams API gesteuert. Sobald der Handshake geklappt hat, löst sich das Promise opened mit einem Objekt auf, das einen readable- und einen writable-Stream enthält.

Der große Vorteil ist der Gegendruck (engl. backpressure): Liest die Anwendung langsamer, als Nachrichten ankommen, puffert der Browser nicht unbegrenzt, sondern bremst das Lesen vom Socket. Beim Schreiben wartet await writer.write(), bis die Daten tatsächlich weitergegeben werden können. Das hilft bei großen Datenmengen oder langsamen Geräten und verhindert, dass der Speicher voll läuft.

Über options.protocols können Unterprotokolle ausgehandelt werden, über options.signal lässt sich der Verbindungsaufbau mit einem AbortController abbrechen (zum Beispiel für einen Timeout). Die Verbindung schließt man mit close({ closeCode, reason }); das Promise closed meldet, wann und warum sie beendet wurde.

Parameter

Name Typ Default Beschreibung
$url Pflicht string | URL URL des WebSocket-Servers. Erlaubt sind die Schemata ws: und wss:. Relative URLs sowie http:/https: werden in modernen Implementierungen passend umgewandelt.
$options object {} Optionales Konfigurationsobjekt mit den folgenden Eigenschaften.
$options.protocols string[] [] Liste der gewünschten Unterprotokolle, z. B. ['chat.v2', 'chat.v1']. Welches der Server gewählt hat, steht nach dem Öffnen in protocol.
$options.signal AbortSignal Signal, mit dem sich der Verbindungsaufbau abbrechen lässt. Wird es vor dem Öffnen ausgelöst, werden opened und closed abgelehnt. Nach dem Handshake hat das Signal keine Wirkung mehr.

Rückgabewert

Typ
WebSocketStream
Beschreibung
Eine neue WebSocketStream-Instanz mit den Eigenschaften url, opened (Promise<{ readable, writable, protocol, extensions }>) und closed (Promise<{ closeCode, reason }>) sowie der Methode close().

Beispiele

Verbindung öffnen, senden und Nachrichten lesen

const wss = new WebSocketStream('wss://echo.example.com/');

const { readable, writable, protocol } = await wss.opened;
console.log('Verbunden, Protokoll:', protocol || '(keins)');

const writer = writable.getWriter();
const reader = readable.getReader();

// Nachricht senden – await berücksichtigt den Gegendruck
await writer.write('Hallo Server!');

// Antworten lesen, bis der Server die Verbindung schließt
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  console.log('Empfangen:', value);
}
Verbunden, Protokoll: (keins) Empfangen: Hallo Server!

Verbindungsaufbau mit Timeout über AbortSignal

const connect = async (url, timeoutMs = 5000) => {
  const wss = new WebSocketStream(url, {
    protocols: ['chat.v2', 'chat.v1'],
    signal: AbortSignal.timeout(timeoutMs)
  });
  try {
    const connection = await wss.opened;
    console.log('Ausgehandeltes Protokoll:', connection.protocol);
    return { wss, ...connection };
  } catch (err) {
    console.error('Verbindung fehlgeschlagen:', err.name);
    throw err;
  }
};

const { wss } = await connect('wss://chat.example.com/socket');
Ausgehandeltes Protokoll: chat.v2

Eingehende Daten per pipeTo weiterverarbeiten und sauber schließen

const wss = new WebSocketStream('wss://ticker.example.com/prices');
const { readable } = await wss.opened;

// Jede Nachricht als JSON parsen und ausgeben
const logger = new WritableStream({
  write(chunk) {
    const { symbol, price } = JSON.parse(chunk);
    console.log(`${symbol}: ${price}`);
  }
});

readable.pipeTo(logger).catch(() => {});

// Nach 10 Sekunden ordentlich beenden
setTimeout(() => wss.close({ closeCode: 1000, reason: 'Fertig' }), 10_000);

const { closeCode, reason } = await wss.closed;
console.log('Geschlossen:', closeCode, reason);
AAPL: 189.42 MSFT: 411.10 Geschlossen: 1000 Fertig

Funktionsprüfung mit Rückfall auf WebSocket

const supportsStreams = 'WebSocketStream' in globalThis;

if (supportsStreams) {
  const wss = new WebSocketStream('wss://example.com/live');
  const { writable } = await wss.opened;
  const writer = writable.getWriter();
  await writer.write(new Uint8Array([1, 2, 3]));
} else {
  const ws = new WebSocket('wss://example.com/live');
  ws.binaryType = 'arraybuffer';
  ws.addEventListener('open', () => ws.send(new Uint8Array([1, 2, 3])));
}
console.log('WebSocketStream verfügbar:', supportsStreams);
WebSocketStream verfügbar: true

// Wichtig · Fallstricke

  • Experimentell und nicht standardisiert: Derzeit nur in Chromium-Browsern (ab Version 124) verfügbar, nicht in Firefox und Safari. Immer mit 'WebSocketStream' in globalThis prüfen und auf WebSocket zurückfallen.
  • Eine ungültige URL oder ein nicht unterstütztes Schema (z. B. ftp:) oder eine URL mit Fragment (#…) löst sofort einen SyntaxError aus. Doppelte oder ungültige Einträge in protocols führen ebenfalls zu einem SyntaxError.
  • Netzwerk- oder Handshake-Fehler werfen keine Ausnahme im Konstruktor, sondern führen zur Ablehnung von opened und closed. Fange beide ab, sonst gibt es Warnungen wegen nicht behandelter Promise-Ablehnungen.
  • Textnachrichten kommen als string an, Binärnachrichten als Uint8Array (nicht als Blob). Geschrieben werden dürfen Strings, ArrayBuffer und ArrayBufferView.
  • Auf HTTPS-Seiten muss wss: verwendet werden (Mixed Content). Der Server sollte den Origin-Header prüfen, weil WebSockets nicht der Same-Origin-Policy/CORS unterliegen.
  • Gültige closeCode-Werte für close() sind 1000 und 3000–4999; reason darf höchstens 123 Byte (UTF-8) lang sein.