Start · Sprachen · JavaScript · Referenz · RTCIceCandidate.candidate

RTCIceCandidate.candidate

Eigenschaft

Schreibgeschützter String mit der vollständigen SDP-Attributzeile des ICE-Kandidaten, z. B. <code>candidate:842163049 1 udp 1677729535 …</code>.

seit JavaScript Baseline: alle modernen Browser (Chrome, Firefox, Kategorie: webapi

Signatur

RTCIceCandidate.candidate

Beschreibung

Die schreibgeschützte Eigenschaft candidate der Schnittstelle RTCIceCandidate liefert einen String, der den Kandidaten im Detail beschreibt. Das Format entspricht dem candidate-Attribut aus SDP (RFC 5245 bzw. RFC 8839), allerdings ohne das Präfix a=. Ein typischer Wert ist candidate:4234997325 1 udp 2043278322 192.168.0.56 44323 typ host.

Der String enthält alle wichtigen Merkmale des Kandidaten, die zusätzlich auch als eigene Eigenschaften verfügbar sind:

  • foundation – Kennung zum Gruppieren gleichartiger Kandidaten (foundation)
  • component – 1 = RTP, 2 = RTCP (component)
  • transport – udp oder tcp (protocol)
  • priority, Adresse und Port (priority, address, port)
  • typ – host, srflx, prflx oder relay (type)
  • optional raddr/rport (relatedAddress, relatedPort) und tcptype

In der Praxis wird candidate vor allem beim Trickle ICE verwendet: Im Handler des icecandidate-Events wird der Kandidat (meist per candidate.toJSON()) über den Signalisierungskanal an die Gegenstelle geschickt, die ihn mit RTCPeerConnection.addIceCandidate() hinzufügt. Ein leerer String "" signalisiert dabei das Ende der Kandidatensammlung für eine Generation (end-of-candidates).

Rückgabewert

Typ
string
Beschreibung
Die SDP-Attributzeile des Kandidaten (ohne a=). Ein leerer String "" kennzeichnet einen end-of-candidates-Hinweis.

Beispiele

Kandidaten beim Sammeln protokollieren und an die Gegenstelle senden

const pc = new RTCPeerConnection({
  iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});

// Platzhalter für einen echten Signalisierungskanal (z. B. WebSocket)
const signaling = { send: (msg) => console.log('Sende:', msg) };

pc.addEventListener('icecandidate', (event) => {
  if (event.candidate) {
    console.log('Kandidat:', event.candidate.candidate);
    signaling.send(JSON.stringify({ ice: event.candidate.toJSON() }));
  } else {
    console.log('ICE-Sammlung abgeschlossen');
  }
});

pc.createDataChannel('chat');
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
Kandidat: candidate:4234997325 1 udp 2043278322 192.168.0.56 44323 typ host generation 0 ... Sende: {"ice":{"candidate":"candidate:4234997325 1 udp ...","sdpMid":"0","sdpMLineIndex":0,...}} ... ICE-Sammlung abgeschlossen

Kandidat aus einem SDP-String erzeugen und auslesen

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

console.log(ice.candidate);
console.log(ice.type, ice.protocol, ice.address, ice.port);
candidate:842163049 1 udp 1677729535 203.0.113.7 51234 typ srflx raddr 192.168.1.20 rport 51234 srflx udp 203.0.113.7 51234

Nur TURN-Relay-Kandidaten weiterleiten (Debugging)

const pc = new RTCPeerConnection({
  iceServers: [{ urls: 'turn:turn.example.com:3478', username: 'user', credential: 'geheim' }]
});

pc.onicecandidate = ({ candidate }) => {
  if (!candidate || candidate.candidate === '') return;
  // Fallback per Regex, falls candidate.type nicht verfügbar ist
  const typ = candidate.type ?? candidate.candidate.match(/ typ (\w+)/)?.[1];
  if (typ === 'relay') {
    console.log('Relay-Kandidat:', candidate.candidate);
  }
};

pc.createDataChannel('test');
await pc.setLocalDescription(await pc.createOffer());
Relay-Kandidat: candidate:1234567890 1 udp 41885439 198.51.100.10 60000 typ relay raddr 203.0.113.7 rport 51234 ...

// Wichtig · Fallstricke

  • Schreibgeschützt: Der Wert wird nur über den Konstruktor new RTCIceCandidate({ candidate, sdpMid, sdpMLineIndex }) gesetzt; Zuweisungen werden ignoriert.
  • Leerer String vs. null: Im icecandidate-Event bedeutet event.candidate === null das Ende aller Sammlungen. Ein Kandidat mit candidate === "" ist ein end-of-candidates-Hinweis und sollte ebenfalls an addIceCandidate() weitergegeben werden, nicht verworfen.
  • Kein a=-Präfix: Wer Kandidaten manuell in SDP einfügt, muss a= voranstellen; umgekehrt beim Parsen entfernen.
  • Datenschutz: Moderne Browser verschleiern lokale Host-Adressen mit mDNS-Namen (z. B. 3f1c…​.local), solange keine Kamera-/Mikrofonfreigabe besteht. Der String kann trotzdem öffentliche IPs (srflx) preisgeben – nicht unnötig protokollieren oder an Dritte weitergeben.
  • Nur candidate senden reicht nicht: Für addIceCandidate() werden auch sdpMid/sdpMLineIndex benötigt – am einfachsten das ganze Objekt per toJSON() serialisieren.
  • Die Einzeleigenschaften (type, address, …) werden in älteren Browsern (v. a. älteres Firefox) teils nicht unterstützt; dann bleibt nur das Parsen des candidate-Strings.