Start · Sprachen · JavaScript · Referenz · RTCIceCandidate

RTCIceCandidate

Schnittstelle

Stellt einen ICE-Kandidaten dar, also eine mögliche Netzwerkadresse samt Protokoll und Port, über die eine <code>RTCPeerConnection</code> aufgebaut werden kann.

seit JavaScript Baseline: alle modernen Browser (seit 2020 vollstä Kategorie: webapi

Signatur

interface RTCIceCandidate

Beschreibung

Ein RTCIceCandidate beschreibt einen einzelnen ICE-Kandidaten (Interactive Connectivity Establishment). Das ist eine mögliche Verbindungsadresse, über die zwei WebRTC-Gegenstellen Daten austauschen können. Dazu gehören lokale Host-Adressen, per STUN ermittelte öffentliche Adressen (srflx) und TURN-Relay-Adressen (relay). Der Browser sammelt diese Kandidaten selbstständig, sobald eine RTCPeerConnection eine lokale Beschreibung erhalten hat, und meldet sie über das Ereignis icecandidate.

Typischer Ablauf: Du empfängst im icecandidate-Handler ein RTCIceCandidate-Objekt, wandelst es mit toJSON() in ein serialisierbares Objekt um und schickst es über deinen Signalisierungskanal (z. B. WebSocket) an die Gegenstelle. Dort übergibst du es an RTCPeerConnection.addIceCandidate(). Dieses Verfahren heißt Trickle ICE: Die Kandidaten werden einzeln verschickt, sobald sie gefunden werden, und nicht erst gesammelt.

Die wichtigsten schreibgeschützten Eigenschaften sind candidate (die SDP-Zeile mit dem Kandidaten), sdpMid, sdpMLineIndex und usernameFragment. Außerdem gibt es die aus der Kandidatenzeile ausgelesenen Felder foundation, component, priority, address, protocol, port, type, tcpType, relatedAddress und relatedPort.

Den Konstruktor brauchst du selten. addIceCandidate() nimmt auch direkt ein einfaches Objekt (RTCIceCandidateInit) entgegen. Nützlich ist new RTCIceCandidate() vor allem, wenn du empfangene Kandidaten vorab auswerten oder filtern willst.

Parameter

Name Typ Default Beschreibung
$candidateInfo RTCIceCandidateInit {} Objekt für den Konstruktor new RTCIceCandidate(candidateInfo) mit den Feldern candidate (string, SDP-Zeile a=candidate:… ohne das Präfix a=), sdpMid (string|null), sdpMLineIndex (number|null) und usernameFragment (string|null). Mindestens sdpMid oder sdpMLineIndex muss gesetzt sein, sonst wird ein TypeError ausgelöst.

Rückgabewert

Typ
RTCIceCandidate
Beschreibung
Ein neues RTCIceCandidate-Objekt. Die Eigenschaften wie address, port oder type werden aus dem Kandidaten-String ausgelesen und sind schreibgeschützt.

Beispiele

Kandidaten sammeln und per WebSocket versenden (Trickle ICE)

const ws = new WebSocket('wss://signal.example.com');
const pc = new RTCPeerConnection({
  iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});

pc.addEventListener('icecandidate', ({ candidate }) => {
  if (candidate) {
    // RTCIceCandidate in serialisierbares Objekt umwandeln
    ws.send(JSON.stringify({ type: 'candidate', candidate: candidate.toJSON() }));
  } else {
    // null bedeutet: Sammeln abgeschlossen
    ws.send(JSON.stringify({ type: 'end-of-candidates' }));
  }
});

pc.createDataChannel('chat');
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);

Empfangene Kandidaten der Gegenstelle hinzufügen

ws.addEventListener('message', async (event) => {
  const msg = JSON.parse(event.data);
  if (msg.type === 'candidate') {
    try {
      await pc.addIceCandidate(new RTCIceCandidate(msg.candidate));
    } catch (err) {
      console.error('Kandidat abgelehnt:', err);
    }
  } else if (msg.type === 'end-of-candidates') {
    await pc.addIceCandidate(); // signalisiert das Ende der Kandidaten
  }
});

Kandidaten mit dem Konstruktor erzeugen und auswerten

const cand = new RTCIceCandidate({
  candidate: 'candidate:842163049 1 udp 1677729535 203.0.113.7 54321 typ srflx raddr 192.168.1.20 rport 54321 generation 0',
  sdpMid: '0',
  sdpMLineIndex: 0
});

console.log(cand.type, cand.protocol, cand.address, cand.port);
console.log(cand.relatedAddress);
console.log(JSON.stringify(cand.toJSON()));
srflx udp 203.0.113.7 54321 192.168.1.20 {"candidate":"candidate:842163049 1 udp 1677729535 203.0.113.7 54321 typ srflx raddr 192.168.1.20 rport 54321 generation 0","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":null}

Nur TURN-Relay-Kandidaten durchlassen

pc.addEventListener('icecandidate', ({ candidate }) => {
  if (!candidate) return;
  if (candidate.type === 'relay') {
    sendToPeer(candidate.toJSON());
  } else {
    console.log('Verworfen:', candidate.type, candidate.address);
  }
});

function sendToPeer(data) {
  ws.send(JSON.stringify({ type: 'candidate', candidate: data }));
}
Verworfen: host 5f1c…-….local

// Wichtig · Fallstricke

  • Das Ende-Signal: Im icecandidate-Ereignis ist event.candidate === null, wenn das Sammeln beendet ist. Manche Browser liefern vorher zusätzlich einen Kandidaten mit leerem candidate-String. Behandle beide Fälle und schicke sie nicht als normale Kandidaten weiter.
  • Reihenfolge beachten: addIceCandidate() schlägt fehl (InvalidStateError), wenn noch keine remoteDescription gesetzt ist. Früh eintreffende Kandidaten solltest du zwischenspeichern und erst nach setRemoteDescription() hinzufügen.
  • Serialisierung: Ein RTCIceCandidate kannst du nicht direkt sinnvoll per postMessage oder ohne toJSON() verschicken. Übertrage immer candidate.toJSON(). JSON.stringify() ruft diese Methode automatisch auf.
  • Datenschutz: Host-Kandidaten verraten lokale IP-Adressen. Moderne Browser verschleiern sie deshalb mit mDNS-Namen (*.local), sodass address keine echte IP enthalten muss. Mit iceTransportPolicy: 'relay' erzwingst du reine TURN-Verbindungen.
  • Kompatibilität: In allen modernen Browsern verfügbar. Die ausgelesenen Felder (address, type usw.) unterstützt Firefox erst seit Version 68. Ältere Safari-Versionen können usernameFragment als null liefern. Veralteter Code nutzt noch das Präfix webkitRTCIceCandidate oder mozRTCIceCandidate, das ist heute nicht mehr nötig.
  • Unter Node.js gibt es diese Schnittstelle nicht. Dort brauchst du Bibliotheken wie wrtc oder werift.