Signatur
Beschreibung
Das Ereignis closing wird an einem RTCDataChannel ausgelöst, sobald der zugrunde liegende Datentransport (ein SCTP-Stream) zu schließen beginnt. Dabei wechselt readyState von "open" auf "closing". Ab diesem Zeitpunkt können Sie keine neuen Nachrichten mehr mit send() verschicken. Nachrichten, die schon in der Warteschlange stehen (bufferedAmount), werden aber möglicherweise noch übertragen. Sobald der Kanal vollständig geschlossen ist, folgt das Ereignis close.
Sie können einen Handler auf zwei Arten registrieren: mit addEventListener("closing", handler) oder über die Eigenschaft onclosing. Das Ereignisobjekt ist ein einfaches Event ohne zusätzliche Eigenschaften. Es steigt nicht auf (bubbelt nicht) und lässt sich nicht abbrechen.
Wofür ist das nützlich? Mit closing erfahren Sie früh, dass die Verbindung abgebaut wird. Das ist vor allem wichtig, wenn die Gegenseite den Kanal schließt. So können Sie zum Beispiel die Oberfläche anpassen („Verbindung wird getrennt …“), Eingabefelder sperren oder den Zustand Ihrer Anwendung sichern, bevor das endgültige close eintrifft.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname, immer "closing". |
|
| $handler Pflicht | (event: Event) => void | Die Rückruffunktion. Sie erhält ein einfaches Event-Objekt; event.target ist der betroffene RTCDataChannel. |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Einstellungen für addEventListener, etwa { once: true } oder { signal }. |
Rückgabewert
addEventListener gibt nichts zurück. Die Rückruffunktion erhält ein Event-Objekt.Beispiele
Schließen der Gegenseite mit addEventListener erkennen (lokale Schleife)
// Zwei lokale Peers, die direkt miteinander verbunden werden
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
pc1.onicecandidate = (e) => e.candidate && pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = (e) => e.candidate && pc1.addIceCandidate(e.candidate);
const sender = pc1.createDataChannel('chat');
pc2.addEventListener('datachannel', ({ channel }) => {
channel.addEventListener('closing', () => {
console.log('closing – readyState:', channel.readyState);
});
channel.addEventListener('close', () => {
console.log('close – readyState:', channel.readyState);
});
});
sender.addEventListener('open', () => {
// Die Gegenseite schließt den Kanal → auf pc2 wird closing ausgelöst
setTimeout(() => sender.close(), 500);
});
const offer = await pc1.createOffer();
await pc1.setLocalDescription(offer);
await pc2.setRemoteDescription(offer);
const answer = await pc2.createAnswer();
await pc2.setLocalDescription(answer);
await pc1.setRemoteDescription(answer);
Oberfläche über onclosing sperren
const setupChannelUi = (channel) => {
const input = document.querySelector('#message');
const status = document.querySelector('#status');
channel.onopen = () => {
input.disabled = false;
status.textContent = 'Verbunden';
};
// Früh reagieren: ab jetzt schlägt send() fehl
channel.onclosing = () => {
input.disabled = true;
status.textContent = 'Verbindung wird getrennt …';
};
channel.onclose = () => {
status.textContent = 'Getrennt';
};
};
const pc = new RTCPeerConnection();
pc.ondatachannel = ({ channel }) => setupChannelUi(channel);
Listener mit removeEventListener wieder entfernen
const pc = new RTCPeerConnection();
const channel = pc.createDataChannel('telemetry');
const onClosing = (event) => {
console.warn(`Kanal "${event.target.label}" wird geschlossen`);
};
channel.addEventListener('closing', onClosing);
// Später, z. B. wenn die Komponente entfernt wird:
channel.removeEventListener('closing', onClosing);
// Alternativ bei Nutzung der Property:
channel.onclosing = null;
// Wichtig · Fallstricke
- Wann wird das Ereignis ausgelöst? Laut Spezifikation feuert
closingnur, wenn das Schließen nicht durch einen Aufruf vonclose()auf demselben Kanal ausgelöst wurde. Typische Fälle sind: Die Gegenseite schließt den Kanal, oder der Transport wird zurückgesetzt. Rufen Sie selbstclose()auf, springtreadyStatezwar direkt auf"closing", aber auf dieser Seite folgt nur nochclose. - Browser-Unterstützung: Chromium-basierte Browser (Chrome, Edge, Opera) und Safari unterstützen das Ereignis. Firefox unterstützt
closingbzw.onclosingbisher nicht. Verlassen Sie sich deshalb nie allein darauf, sondern werten Sie immer auchcloseaus. Sie können die Unterstützung so prüfen:'onclosing' in RTCDataChannel.prototype. - Nach
closingwirftsend()einenInvalidStateError. Prüfen Sie deshalb vor dem Sendenchannel.readyState === "open". - Das Ereignis steigt nicht auf und lässt sich nicht abbrechen:
preventDefault()kann das Schließen nicht verhindern. - Wird die ganze
RTCPeerConnectionmitpc.close()geschlossen, werden die Datenkanäle ohneclosing-Ereignis sofort geschlossen.