Signatur
Beschreibung
Die Eigenschaft RTCDataChannelEvent.channel enthält den RTCDataChannel, zu dem ein datachannel-Ereignis auf einer RTCPeerConnection gehört. Das Ereignis wird ausgelöst, wenn die entfernte Gegenstelle mit createDataChannel() einen neuen Datenkanal aushandelt (sogenannte „in-band negotiation“).
Man braucht diese Eigenschaft vor allem auf der empfangenden Seite einer WebRTC-Verbindung: Nur hier erhält man Zugriff auf den Kanal, den die andere Seite angelegt hat. Direkt im Handler sollte man die benötigten Ereignis-Listener (open, message, close, error) registrieren und bei Bedarf binaryType setzen.
Über Eigenschaften wie label, protocol, ordered oder id des gelieferten Kanals kann man mehrere Kanäle voneinander unterscheiden, z. B. einen Chat-Kanal und einen Dateiübertragungs-Kanal.
Rückgabewert
Beispiele
Eingehenden Datenkanal entgegennehmen
const pc = new RTCPeerConnection();
pc.addEventListener('datachannel', (event) => {
const channel = event.channel;
console.log(`Neuer Kanal: ${channel.label}`);
channel.addEventListener('open', () => channel.send('Hallo zurück!'));
channel.addEventListener('message', (e) => console.log('Empfangen:', e.data));
channel.addEventListener('close', () => console.log('Kanal geschlossen'));
});
Mehrere Kanäle anhand des Labels unterscheiden (on-Property)
const pc = new RTCPeerConnection();
const handlers = {
chat: (e) => console.log('Chat:', e.data),
dateien: (e) => console.log('Chunk erhalten:', e.data.byteLength, 'Bytes')
};
pc.ondatachannel = ({ channel }) => {
if (channel.label === 'dateien') {
channel.binaryType = 'arraybuffer';
}
channel.onmessage = handlers[channel.label] ?? ((e) => console.warn('Unbekannter Kanal', channel.label));
};
Vollständige lokale Demo mit zwei Peers
const a = new RTCPeerConnection();
const b = new RTCPeerConnection();
a.onicecandidate = (e) => e.candidate && b.addIceCandidate(e.candidate);
b.onicecandidate = (e) => e.candidate && a.addIceCandidate(e.candidate);
b.ondatachannel = (event) => {
event.channel.onmessage = (e) => console.log('B empfängt:', e.data);
};
const sendChannel = a.createDataChannel('chat');
sendChannel.onopen = () => sendChannel.send('Hallo!');
const verbinden = async () => {
await a.setLocalDescription(await a.createOffer());
await b.setRemoteDescription(a.localDescription);
await b.setLocalDescription(await b.createAnswer());
await a.setRemoteDescription(b.localDescription);
};
verbinden();
// Wichtig · Fallstricke
- Das
datachannel-Ereignis wird nur auf der Gegenseite ausgelöst. WercreateDataChannel()selbst aufruft, bekommt kein Ereignis für den eigenen Kanal, sondern verwendet direkt den Rückgabewert. - Kanäle, die mit
negotiated: trueund festeridangelegt wurden, lösen keindatachannel-Ereignis aus. Beide Seiten müssen sie dann selbst mitcreateDataChannel()erzeugen. - Listener sollten direkt im Handler registriert werden. Setzt man sie erst später (etwa nach einem
await), gehen frühemessage-Ereignisse unter Umständen verloren. - Der Kanal kann beim Eintreffen des Ereignisses bereits den Zustand
openhaben. Deshalb vorherchannel.readyStateprüfen, statt sich nur auf dasopen-Ereignis zu verlassen. - Der Standardwert von
binaryTypeunterscheidet sich je nach Browser (älteres Chrome:"arraybuffer", Spezifikation:"blob"). Deshalb ausdrücklich setzen. - WebRTC funktioniert nur in sicheren Kontexten (HTTPS oder localhost). Die Eigenschaft wird von allen aktuellen Browsern unterstützt.