Signatur
Beschreibung
RTCPeerConnectionIceEvent ist der Ereignistyp, den eine RTCPeerConnection beim Event icecandidate auslöst. Das passiert immer dann, wenn der ICE-Agent einen neuen lokalen Netzwerkkandidaten (Host, Server-Reflexive über STUN oder Relay über TURN) gefunden hat. Die wichtigste Eigenschaft ist candidate. Sie enthält ein RTCIceCandidate-Objekt, das du über deinen Signalisierungskanal (z. B. WebSocket) an die Gegenstelle schicken musst.
Das Interface erbt von Event und hat eine eigene Eigenschaft:
candidate(nur lesbar, TypRTCIceCandidate | null): der gefundene Kandidat. Ist der Wertnull, hat der ICE-Agent die Kandidatensuche für diese Verbindung abgeschlossen (end-of-candidates).
Normalerweise erzeugst du solche Ereignisse nicht selbst, sondern reagierst nur darauf – per pc.addEventListener("icecandidate", handler) oder über die Property pc.onicecandidate. Mit dem Konstruktor new RTCPeerConnectionIceEvent(type, options) kannst du Ereignisse aber auch künstlich erzeugen, etwa für Tests oder Mocks.
Auf der Empfängerseite übergibst du den Kandidaten an RTCPeerConnection.addIceCandidate(). Dieses Vorgehen nennt man Trickle ICE. Der Verbindungsaufbau beginnt dabei schon, bevor alle Kandidaten gefunden sind.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Nur beim Konstruktor: der Name des Ereignisses, in der Praxis immer "icecandidate". |
|
| $options | object | {} | Nur beim Konstruktor: ein EventInit-Objekt mit dem zusätzlichen Feld candidate (RTCIceCandidate | null, Standardwert null). Außerdem sind bubbles, cancelable und composed möglich. |
Rückgabewert
candidate liefert RTCIceCandidate oder null.Beispiele
ICE-Kandidaten per addEventListener an die Gegenstelle senden
const signaling = new WebSocket("wss://example.com/signal");
const pc = new RTCPeerConnection({
iceServers: [{ urls: "stun:stun.l.google.com:19302" }]
});
pc.addEventListener("icecandidate", (event) => {
// event ist ein RTCPeerConnectionIceEvent
if (event.candidate) {
console.log("Neuer Kandidat:", event.candidate.candidate);
signaling.send(JSON.stringify({ type: "candidate", candidate: event.candidate }));
} else {
console.log("Kandidatensuche abgeschlossen");
signaling.send(JSON.stringify({ type: "end-of-candidates" }));
}
});
// Kandidatensuche anstoßen
pc.createDataChannel("chat");
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
Kandidaten auf der Empfängerseite hinzufügen (on-Property)
const pc = new RTCPeerConnection();
const signaling = new WebSocket("wss://example.com/signal");
// Eigene Kandidaten per on-Property versenden
pc.onicecandidate = ({ candidate }) => {
signaling.send(JSON.stringify({ type: "candidate", candidate }));
};
signaling.addEventListener("message", async (msg) => {
const data = JSON.parse(msg.data);
if (data.type === "candidate") {
try {
// null/undefined signalisiert das Ende der Kandidaten
await pc.addIceCandidate(data.candidate ?? undefined);
} catch (err) {
console.error("Kandidat konnte nicht hinzugefügt werden:", err);
}
}
});
Ereignis für Tests künstlich erzeugen
const candidate = new RTCIceCandidate({
candidate: "candidate:1 1 udp 2122260223 192.168.1.10 50000 typ host",
sdpMid: "0",
sdpMLineIndex: 0
});
const event = new RTCPeerConnectionIceEvent("icecandidate", { candidate });
console.log(event instanceof Event);
console.log(event.type, event.candidate.address, event.candidate.type);
const leer = new RTCPeerConnectionIceEvent("icecandidate");
console.log(leer.candidate);
// Wichtig · Fallstricke
- Auf
nullprüfen: Das letzteicecandidate-Event hatcandidate === null. Ohne Prüfung führt ein Zugriff wieevent.candidate.candidatezu einemTypeError. Manche Browser senden zusätzlich einen Kandidaten mit leerem Stringcandidate: \"\"als Ende-Signal. - Reihenfolge beim Empfänger:
addIceCandidate()wirft einen Fehler, solange keine Remote-Beschreibung gesetzt ist. Treffen Kandidaten vor dem Offer oder Answer ein, puffere sie, bissetRemoteDescription()abgeschlossen ist. - Datenschutz: Host-Kandidaten können lokale IP-Adressen enthalten. Moderne Browser verschleiern sie daher mit mDNS-Namen (
*.local). Die Kandidaten sollten nur über einen vertrauenswürdigen, verschlüsselten Signalisierungskanal (wss://) übertragen werden. - Veraltet: Die frühere Eigenschaft
urlist veraltet. Nutze stattdessenevent.candidate.urlbzw.relayProtocol. - Kompatibilität: Wird von allen modernen Browsern unterstützt. In Node.js gibt es das Interface nicht nativ, nur über Bibliotheken wie
wrtcoderwerift. - Kandidaten werden erst gesucht, wenn
setLocalDescription()aufgerufen wurde und mindestens ein Track oder Datenkanal existiert.