Signatur
Beschreibung
Das open-Ereignis wird an einem RTCDataChannel ausgelöst, sobald dessen Transport (SCTP über DTLS) aufgebaut ist und der Kanal Daten übertragen kann. Zu diesem Zeitpunkt wechselt readyState von "connecting" auf "open". Erst ab jetzt darf send() aufgerufen werden. Ein früherer Aufruf wirft einen InvalidStateError.
Einen Handler registriert man entweder mit addEventListener("open", handler) oder über die Eigenschaft onopen. Das übergebene Objekt ist ein einfaches Event und enthält keine zusätzlichen Daten. event.target verweist auf den geöffneten Kanal.
Typische Einsatzzwecke:
- Die Oberfläche freischalten, zum Beispiel ein Chat-Eingabefeld.
- Zwischengespeicherte Nachrichten aus einer Warteschlange senden.
- Einen Begrüßungs- oder Handshake-Nachricht auf Anwendungsebene schicken.
Das Ereignis tritt sowohl auf der Seite auf, die den Kanal mit createDataChannel() erzeugt, als auch auf der Gegenseite, die den Kanal über das datachannel-Ereignis der RTCPeerConnection erhält. Bei ausgehandelten Kanälen (negotiated: true) wird es auf beiden Seiten ausgelöst.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp, hier immer "open". |
|
| $handler Pflicht | (event: Event) => void | Callback, der beim Öffnen des Kanals aufgerufen wird. event.target ist der RTCDataChannel. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie bei addEventListener, zum Beispiel { once: true } oder { signal }. |
Rückgabewert
addEventListener gibt keinen Wert zurück. Der Handler erhält ein Event-Objekt ohne zusätzliche Eigenschaften.Beispiele
Kanal erzeugen und beim Öffnen senden (addEventListener)
const pc = new RTCPeerConnection();
const channel = pc.createDataChannel('chat');
channel.addEventListener('open', (event) => {
console.log('Kanal offen:', event.target.label, event.target.readyState);
channel.send('Hallo Gegenstelle!');
});
channel.addEventListener('message', (e) => console.log('Empfangen:', e.data));
// ... anschließend Signalisierung (Angebot/Antwort, ICE) durchführen
Gegenseite: onopen am empfangenen Kanal
const pc = new RTCPeerConnection();
pc.ondatachannel = ({ channel }) => {
channel.onopen = () => {
console.log(`Kanal "${channel.label}" bereit`);
document.querySelector('#send').disabled = false;
};
channel.onclose = () => {
document.querySelector('#send').disabled = true;
};
};
Nachrichten-Warteschlange bis zum Öffnen puffern
const pc = new RTCPeerConnection();
const channel = pc.createDataChannel('sync');
const queue = [];
const sendSafe = (msg) => {
if (channel.readyState === 'open') {
channel.send(msg);
} else {
queue.push(msg);
}
};
channel.addEventListener('open', () => {
while (queue.length) channel.send(queue.shift());
console.log('Warteschlange geleert');
}, { once: true });
sendSafe(JSON.stringify({ type: 'hello' }));
Auf das Öffnen per Promise warten und Listener entfernen
const waitForOpen = (channel, timeoutMs = 10000) =>
new Promise((resolve, reject) => {
if (channel.readyState === 'open') return resolve(channel);
const onOpen = () => { cleanup(); resolve(channel); };
const timer = setTimeout(() => { cleanup(); reject(new Error('Timeout')); }, timeoutMs);
const cleanup = () => {
clearTimeout(timer);
channel.removeEventListener('open', onOpen);
};
channel.addEventListener('open', onOpen);
});
const pc = new RTCPeerConnection();
const ch = pc.createDataChannel('files');
waitForOpen(ch)
.then(() => ch.send('bereit'))
.catch((err) => console.error(err.message));
// Wichtig · Fallstricke
- Nicht zu früh senden: Rufen Sie
send()vor demopen-Ereignis auf, also beireadyState === "connecting", wird einInvalidStateErrorgeworfen. Puffern Sie Nachrichten vorher oder prüfen SiereadyState. - Handler rechtzeitig registrieren: Beim empfangenen Kanal (
datachannel-Ereignis) ist der Kanal manchmal schon offen, bevor der Handler gesetzt wird. Registrieren Sie den Handler deshalb sofort imdatachannel-Handler und prüfen Sie zur Sicherheit zusätzlichreadyState. - Signalisierung nötig:
openwird nie ausgelöst, wenn der Austausch von Angebot und Antwort sowie der ICE-Kandidaten nicht abgeschlossen ist. Hinter restriktiven NATs ohne TURN-Server bleibt der Kanal aufconnectingstehen, daher einen Timeout vorsehen. - Das Ereignis ist ein einfaches
Event, es wird nicht durch den DOM propagiert (bubbles: false) und ist nicht abbrechbar. - Kompatibilität: Wird von allen aktuellen Browsern unterstützt. In Node.js gibt es keine eingebaute Unterstützung, dort sind Bibliotheken wie
wrtcodernode-datachannelnötig. WebRTC verlangt einen sicheren Kontext (HTTPS oder localhost).