Signatur
Beschreibung
Die Schnittstelle CloseEvent beschreibt das Ereignis, das ein WebSocket-Objekt beim Schließen der Verbindung auslöst. Du fängst es mit socket.addEventListener("close", handler) oder über die Eigenschaft socket.onclose ab. Es erbt alle Eigenschaften von Event und hat zusätzlich drei schreibgeschützte Eigenschaften:
code(number): der Close-Code nach RFC 6455, z. B.1000(normal geschlossen),1001(Gegenseite geht weg),1006(Verbindung abnormal abgebrochen, ohne Close-Frame),1008(Richtlinienverstoß),1011(interner Serverfehler).reason(string): der Grund, den die Gegenseite mitgeschickt hat. Oft ist er leer.wasClean(boolean):true, wenn beide Seiten den Close-Handshake ordnungsgemäß abgeschlossen haben.
In der Praxis wertest du ein CloseEvent vor allem aus, um zu entscheiden, ob die Verbindung automatisch neu aufgebaut werden soll. Das ist z. B. sinnvoll bei 1006 oder 1011, aber nicht bei 1000 oder bei Codes, die der eigene Server für „nicht berechtigt“ nutzt. Außerdem kannst du Fehlermeldungen im Protokoll oder in der Oberfläche anzeigen.
Mit dem Konstruktor new CloseEvent(type, options) erzeugst du selbst Ereignisse, etwa für Tests oder für eigene Abstraktionen auf Basis von EventTarget.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, üblicherweise "close". Groß-/Kleinschreibung wird beachtet. |
|
| $options | CloseEventInit | {} | Optionales Objekt mit den EventInit-Feldern (bubbles, cancelable, composed) und zusätzlich code (number, Standard 0), reason (string, Standard "") und wasClean (boolean, Standard false). |
Rückgabewert
CloseEvent-Objekt zurück. Seine Eigenschaften code, reason und wasClean sind schreibgeschützt.Beispiele
Close-Ereignis mit addEventListener auswerten
const socket = new WebSocket("wss://echo.websocket.org");
socket.addEventListener("open", () => {
// Verbindung nach kurzer Zeit normal schließen
setTimeout(() => socket.close(1000, "Sitzung beendet"), 500);
});
socket.addEventListener("close", (event) => {
console.log(event instanceof CloseEvent);
console.log(`Code: ${event.code}, Grund: "${event.reason}", sauber: ${event.wasClean}`);
});
Automatisch neu verbinden mit onclose und Backoff
const NICHT_ERNEUT = new Set([1000, 1008, 4001]); // 4001 = eigener Code für „nicht autorisiert“
const connect = (url, versuch = 0) => {
const socket = new WebSocket(url);
socket.onopen = () => {
versuch = 0;
console.log("Verbunden");
};
socket.onclose = ({ code, reason, wasClean }) => {
console.warn(`Getrennt (${code}) ${reason || "ohne Grund"}, sauber: ${wasClean}`);
if (NICHT_ERNEUT.has(code)) return;
const wartezeit = Math.min(30_000, 1000 * 2 ** versuch);
console.log(`Neuer Versuch in ${wartezeit} ms`);
setTimeout(() => connect(url, versuch + 1), wartezeit);
};
return socket;
};
connect("wss://example.com/live");
CloseEvent per Konstruktor erzeugen (z. B. für Tests)
const target = new EventTarget();
const handler = (e) => console.log(e.type, e.code, e.reason, e.wasClean);
target.addEventListener("close", handler);
target.dispatchEvent(new CloseEvent("close", {
code: 1011,
reason: "Serverfehler",
wasClean: false
}));
// Listener wieder entfernen
target.removeEventListener("close", handler);
target.dispatchEvent(new CloseEvent("close")); // keine Ausgabe mehr
// Wichtig · Fallstricke
- Code 1006 wird nur lokal gesetzt: Er wird nie übertragen, sondern vom Browser vergeben, wenn die Verbindung ohne Close-Frame abbricht, etwa bei Netzwerkfehler, abgelehntem Handshake, CORS- oder TLS-Problem. Aus Sicherheitsgründen gibt der Browser keine genaueren Gründe preis. Vorher wird meist ein unspezifisches
error-Ereignis ausgelöst. close()akzeptiert nur bestimmte Codes: Beim eigenen Aufruf vonsocket.close(code, reason)sind nur1000und3000–4999erlaubt. Andere Codes lösen einenInvalidAccessErroraus. Istreasonin UTF-8 länger als 123 Byte, gibt es einenSyntaxError.- Eigene Codes: Der Bereich
4000–4999ist für anwendungseigene Codes gedacht,3000–3999für Bibliotheken und Frameworks. reasonist keine vertrauenswürdige Eingabe: Der Text stammt vom Server. Gib ihn nicht ungeprüft perinnerHTMLaus, sondern verwendetextContent.- Kompatibilität: Das Interface wird von allen modernen Browsern unterstützt. In Node.js steht es ab Version 22 global zur Verfügung, zusammen mit dem nativen
WebSocket. Bibliotheken wiewsliefern eigene Ereignisobjekte, die nur ähnlich aufgebaut sind.