Start · Sprachen · JavaScript · Referenz · WebSocket: close

WebSocket: close

Ereignis

Wird ausgelöst, wenn die Verbindung eines <code>WebSocket</code> geschlossen wurde – egal ob regulär, durch den Server oder wegen eines Fehlers.

seit JavaScript Baseline: alle Browser (seit 2015 weit verfügbar) Kategorie: webapi

Signatur

webSocket.addEventListener("close", handler)

Beschreibung

Das close-Ereignis eines WebSocket-Objekts wird ausgelöst, sobald die Verbindung endgültig geschlossen ist und readyState den Wert WebSocket.CLOSED (3) hat. Den Handler registriert man entweder mit addEventListener("close", handler) oder über die Eigenschaft onclose.

Der Handler bekommt ein CloseEvent übergeben. Es enthält den Statuscode (code), einen optionalen Grund als Text (reason) und das Flag wasClean. Dieses Flag zeigt an, ob der Schließ-Handshake ordnungsgemäß abgeschlossen wurde. Damit lässt sich unterscheiden, ob der Client oder Server die Verbindung gewollt beendet hat (z. B. Code 1000) oder ob sie abgerissen ist (z. B. Code 1006).

Typische Einsatzzwecke sind automatisches Wiederverbinden mit Backoff-Strategie, das Aktualisieren der Oberfläche (Status „offline“ anzeigen), das Aufräumen von Timern (Heartbeats) und das Protokollieren von Verbindungsabbrüchen. Das Ereignis wird bei jedem Schließen genau einmal ausgelöst, auch wenn die Verbindung nie zustande kam. In diesem Fall kommt vorher ein error-Ereignis.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname, hier immer "close".
$handler Pflicht (event: CloseEvent) => void Callback, der ein CloseEvent mit den Eigenschaften code (number), reason (string) und wasClean (boolean) erhält.
$options boolean | AddEventListenerOptions false Optionale Listener-Optionen wie once oder signal (zum Entfernen per AbortController).

Beispiele

Grund des Schließens auswerten (addEventListener)

const socket = new WebSocket('wss://echo.websocket.org');

socket.addEventListener('open', () => {
  // Verbindung regulär mit Code 1000 schließen
  socket.close(1000, 'Sitzung beendet');
});

socket.addEventListener('close', (event) => {
  console.log('Code:', event.code);
  console.log('Grund:', event.reason);
  console.log('Sauber geschlossen:', event.wasClean);
});
Code: 1000 Grund: Sitzung beendet Sauber geschlossen: true

Automatisches Wiederverbinden mit exponentiellem Backoff

const connect = (url, attempt = 0) => {
  const socket = new WebSocket(url);

  socket.onopen = () => {
    console.log('Verbunden');
    attempt = 0; // Zähler nach Erfolg zurücksetzen
  };

  socket.onclose = (event) => {
    // 1000 = gewolltes Schließen -> nicht neu verbinden
    if (event.code === 1000) return;

    const delay = Math.min(30000, 1000 * 2 ** attempt);
    console.warn(`Verbindung verloren (Code ${event.code}), neuer Versuch in ${delay} ms`);
    setTimeout(() => connect(url, attempt + 1), delay);
  };

  return socket;
};

connect('wss://example.com/live');
Verbindung verloren (Code 1006), neuer Versuch in 1000 ms

Listener über AbortController entfernen

const socket = new WebSocket('wss://example.com/chat');
const controller = new AbortController();

const onClose = (event) => {
  document.querySelector('#status').textContent = `Offline (${event.code})`;
};

socket.addEventListener('close', onClose, { signal: controller.signal });

// Später, z. B. beim Verlassen der Ansicht:
controller.abort(); // entspricht socket.removeEventListener('close', onClose)

Heartbeat-Timer beim Schließen aufräumen

const socket = new WebSocket('wss://example.com/stream');
let heartbeat;

socket.onopen = () => {
  heartbeat = setInterval(() => socket.send('ping'), 25000);
};

socket.onclose = () => {
  clearInterval(heartbeat);
  console.log('Heartbeat gestoppt, readyState:', socket.readyState);
};
Heartbeat gestoppt, readyState: 3

// Wichtig · Fallstricke

  • Code 1006 (Abnormal Closure) wird nie über das Netzwerk gesendet, sondern vom Browser gesetzt, wenn die Verbindung ohne Schließ-Frame abreißt, z. B. bei Netzwerkabbruch, abgelehntem Handshake, CORS-/Zertifikatsproblemen oder einem nicht erreichbaren Server. Aus Sicherheitsgründen gibt der Browser keine genaueren Details preis.
  • Bei einem Verbindungsfehler wird zuerst error und danach close ausgelöst. Logik zum Wiederverbinden gehört daher in den close-Handler, sonst läuft sie doppelt.
  • socket.close(code, reason) akzeptiert nur 1000 oder Codes im Bereich 3000–4999. Andere Werte lösen eine InvalidAccessError-DOMException aus. reason darf höchstens 123 Byte (UTF-8) lang sein, sonst gibt es einen SyntaxError.
  • Ein WebSocket-Objekt kann nach dem Schließen nicht wiederverwendet werden. Zum Wiederverbinden muss immer eine neue Instanz erzeugt werden.
  • Beim Neuladen oder Schließen des Tabs wird close oft nicht mehr zuverlässig ausgeführt. Für Aufräumarbeiten auf dem Server sollte man sich nicht darauf verlassen.
  • Ein direkt gesetztes onclose überschreibt einen vorher gesetzten onclose-Handler. Mit addEventListener lassen sich dagegen mehrere Handler registrieren.