Start · Sprachen · JavaScript · Referenz · RTCDataChannel: message

RTCDataChannel: message

Ereignis

Wird auf einem <code>RTCDataChannel</code> ausgelöst, sobald eine Nachricht vom entfernten Peer eingetroffen ist. Der Handler erhält ein <code>MessageEvent</code>.

seit JavaScript Baseline: alle modernen Browser (seit 2020) Kategorie: webapi

Signatur

dataChannel.addEventListener("message", handler)

Beschreibung

Das Ereignis message tritt auf einem RTCDataChannel ein, sobald der entfernte Peer mit send() Daten geschickt hat und diese vollständig angekommen sind. Den Handler registriert man entweder mit dataChannel.addEventListener("message", handler) oder über die Eigenschaft dataChannel.onmessage = handler. Das Ereignis steigt nicht auf (kein Bubbling) und lässt sich nicht abbrechen.

Der Handler bekommt ein MessageEvent. Die empfangene Nachricht steckt in event.data. Welchen Typ sie hat, hängt davon ab, was gesendet wurde: Texte kommen als string an, Binärdaten je nach dataChannel.binaryType als ArrayBuffer (Standard in den meisten Browsern) oder als Blob.

Typische Einsatzfälle sind Chat-Nachrichten, Spielzustände, Dateiübertragungen in Stücken (Chunks) oder Steuerbefehle zwischen zwei Peers, und zwar ohne Umweg über einen Server. Strukturierte Daten serialisiert man meist als JSON. Große Binärdaten sollte man in Stücke aufteilen und beim Empfänger wieder zusammensetzen.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Name des Ereignisses, hier immer "message".
$handler Pflicht (event: MessageEvent) => void Callback, der für jede empfangene Nachricht aufgerufen wird. Die Nutzdaten liegen in event.data (string, ArrayBuffer oder Blob).
$options boolean | AddEventListenerOptions false Optionen wie once oder signal (zum Abmelden per AbortController).

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler erhält ein MessageEvent mit den Eigenschaften data, origin, lastEventId, source und ports. Für WebRTC ist praktisch nur data von Bedeutung.

Beispiele

Textnachrichten mit addEventListener empfangen

const pc = new RTCPeerConnection();
const channel = pc.createDataChannel("chat");

channel.addEventListener("message", (event) => {
  console.log("Peer schreibt:", event.data);
});

channel.addEventListener("open", () => {
  channel.send("Hallo!");
});
Peer schreibt: Hallo zurück!

JSON-Nachrichten über die onmessage-Eigenschaft verarbeiten

const pc = new RTCPeerConnection();

// Auf der Gegenseite geöffneten Kanal entgegennehmen
pc.ondatachannel = ({ channel }) => {
  channel.onmessage = (event) => {
    try {
      const msg = JSON.parse(event.data);
      if (msg.type === "move") {
        console.log(`Spieler bewegt sich nach ${msg.x}/${msg.y}`);
      }
    } catch {
      console.warn("Ungültige Nachricht:", event.data);
    }
  };
};
Spieler bewegt sich nach 10/20

Binäre Datei-Chunks empfangen und zusammensetzen

const pc = new RTCPeerConnection();
const channel = pc.createDataChannel("file");
channel.binaryType = "arraybuffer";

const chunks = [];
channel.addEventListener("message", ({ data }) => {
  if (typeof data === "string" && data === "EOF") {
    const blob = new Blob(chunks);
    console.log(`Datei empfangen: ${blob.size} Bytes`);
    chunks.length = 0;
    return;
  }
  chunks.push(data); // ArrayBuffer
});
Datei empfangen: 524288 Bytes

Listener mit AbortController wieder entfernen

const pc = new RTCPeerConnection();
const channel = pc.createDataChannel("status");
const controller = new AbortController();

const onMessage = (event) => console.log("Status:", event.data);
channel.addEventListener("message", onMessage, { signal: controller.signal });

// Später: Listener abmelden
controller.abort();
// alternativ: channel.removeEventListener("message", onMessage);
// bzw. bei der Property-Variante: channel.onmessage = null;

// Wichtig · Fallstricke

  • Typ von event.data prüfen: Text- und Binärnachrichten können auf demselben Kanal gemischt ankommen. Prüfe den Typ, zum Beispiel mit typeof data === "string" oder data instanceof ArrayBuffer.
  • binaryType: Der Standardwert ist "arraybuffer". Ältere Chrome-Versionen unterstützten "blob" nicht. Setze den Wert am besten ausdrücklich.
  • Nachrichtengröße: Nachrichten über etwa 16 KiB bis 256 KiB (je nach Browser und SCTP-Aushandlung, siehe pc.sctp.maxMessageSize) können fehlschlagen oder den Kanal blockieren. Große Daten solltest du in Stücke aufteilen und den Datenfluss beim Senden mit bufferedAmount und bufferedamountlow steuern.
  • Reihenfolge und Zuverlässigkeit: Wird der Kanal mit ordered: false oder maxRetransmits bzw. maxPacketLifeTime angelegt, können Nachrichten in anderer Reihenfolge ankommen oder ganz verloren gehen.
  • Sicherheit: Empfangene Daten sind nicht vertrauenswürdig. Füge sie nie ungeprüft per innerHTML ein (XSS-Gefahr), sondern nutze textContent, und fange Fehler bei JSON.parse ab.
  • Den Handler vor dem Ereignis open zu registrieren, ist unbedenklich. Auf der Gegenseite bekommt man den Kanal über das Ereignis datachannel von RTCPeerConnection.