Start · Sprachen · JavaScript · Referenz · RTCIceCandidate.priority

RTCIceCandidate.priority

Eigenschaft

Schreibgeschützte Zahl mit der ICE-Priorität des Kandidaten. Je höher der Wert, desto eher wird der Kandidat für die Verbindung bevorzugt.

seit JavaScript Baseline: alle modernen Browser (Chrome 74+, Firef Kategorie: webapi

Signatur

RTCIceCandidate.priority

Beschreibung

Die schreibgeschützte Eigenschaft priority eines RTCIceCandidate enthält die Priorität des Kandidaten als vorzeichenlose 32-Bit-Ganzzahl. Der Browser liest den Wert direkt aus dem Kandidaten-String (candidate-Attribut) aus: Er steht dort im vierten Feld, z. B. candidate:842163049 1 udp 1677729535 …. Beim Aushandeln einer Verbindung (ICE-Negotiation) prüfen die Peers die Kandidatenpaare in der Reihenfolge ihrer Priorität. Ein höherer Wert bedeutet also: Dieser Kandidat wird bevorzugt.

Nach RFC 8445 wird die Priorität so berechnet: 2^24 × Typ-Präferenz + 2^8 × lokale Präferenz + (256 − Komponenten-ID). Aus den oberen 8 Bit lässt sich deshalb der Kandidatentyp ablesen. Übliche Werte sind 126 für host, 110 für prflx, 100 für srflx und 0 für relay (TURN). Die mittleren 16 Bit enthalten die lokale Präferenz, z. B. für Netzwerkschnittstelle oder IP-Version. Die unteren 8 Bit kodieren die Komponente (RTP = 1, RTCP = 2).

In der Praxis braucht man priority vor allem zur Fehlersuche und Analyse: um zu verstehen, warum eine Verbindung über TURN statt direkt läuft, um gesammelte Kandidaten sortiert zu protokollieren oder um in Signalisierungs-Logs Auffälligkeiten zu erkennen. Die Auswahl des Kandidatenpaars selbst übernimmt der Browser. Anwendungscode muss die Priorität dafür nicht auswerten.

Rückgabewert

Typ
number | null
Beschreibung
Vorzeichenlose 32-Bit-Ganzzahl (unsigned long) mit der Priorität des Kandidaten. null, wenn der Kandidat nicht initialisiert wurde oder sich der candidate-String nicht auswerten ließ.

Beispiele

Priorität gesammelter Kandidaten protokollieren

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

pc.addEventListener('icecandidate', ({ candidate }) => {
  // candidate === null signalisiert das Ende der Kandidatensuche
  if (!candidate) {
    console.log('ICE-Gathering abgeschlossen');
    return;
  }
  console.log(`${candidate.type} ${candidate.protocol} ${candidate.address ?? '(verborgen)'} → Priorität ${candidate.priority}`);
});

pc.createDataChannel('test');
await pc.setLocalDescription(await pc.createOffer());
host udp (verborgen) → Priorität 2122260223 srflx udp 203.0.113.7 → Priorität 1686052607 ICE-Gathering abgeschlossen

Priorität in ihre Bestandteile zerlegen (RFC 8445)

const decodePriority = (priority) => ({
  // >>> statt >>, da Werte über 2^31 sonst negativ würden
  typePreference: priority >>> 24,
  localPreference: (priority >>> 8) & 0xffff,
  componentId: 256 - (priority & 0xff)
});

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

console.log(cand.priority);
console.log(decodePriority(cand.priority));
1677729535 { typePreference: 100, localPreference: 30, componentId: 1 }

Entfernte Kandidaten nach Priorität sortieren

const remoteCandidates = [];

// Wird z. B. vom Signalisierungskanal aufgerufen
const onRemoteCandidate = async (pc, init) => {
  const candidate = new RTCIceCandidate(init);
  remoteCandidates.push(candidate);
  await pc.addIceCandidate(candidate);
};

const logSorted = () => {
  const sorted = [...remoteCandidates]
    .filter((c) => c.priority !== null)
    .sort((a, b) => b.priority - a.priority);
  console.table(sorted.map(({ type, protocol, priority }) => ({ type, protocol, priority })));
};

// Wichtig · Fallstricke

  • Nur lesbar: priority lässt sich nicht direkt setzen. Wer einen anderen Wert braucht, muss einen neuen RTCIceCandidate mit geändertem candidate-String erzeugen. Das ist selten sinnvoll und kann die ICE-Aushandlung stören.
  • Vorzeichenlos: Die Werte können bis 2^32 − 1 reichen. Für Bitoperationen deshalb >>> statt >> verwenden, sonst entstehen negative Zahlen.
  • null-Werte: Wurde ein Kandidat ohne auswertbaren candidate-String erzeugt, ist priority null. Auch das Ende-Signal im icecandidate-Ereignis (event.candidate === null) sollte man vor dem Zugriff abfangen.
  • Browserabhängig: Die konkreten Zahlen (vor allem die lokale Präferenz) unterscheiden sich zwischen Browsern und Plattformen. Man sollte sie nur untereinander vergleichen und nicht fest im Code verankern.
  • Kompatibilität: Ältere Firefox-Versionen vor 68 hatten die Eigenschaft nicht. Dort blieb nur, den candidate-String selbst auszuwerten (viertes Feld).
  • Datenschutz: Die Priorität selbst enthält keine IP-Adresse. Zusammen mit Kandidatentyp und lokaler Präferenz verrät sie aber etwas über die Netzwerkumgebung. Kandidaten-Logs deshalb nicht ungefiltert an Dritte übermitteln.