Start · Sprachen · JavaScript · Referenz · RTCTransportStats.selectedCandidatePairId

RTCTransportStats.selectedCandidatePairId

Eigenschaft

Liefert die <code>id</code> des <code>RTCIceCandidatePairStats</code>-Eintrags, der das aktuell ausgewählte ICE-Kandidatenpaar dieses Transports beschreibt.

seit JavaScript Chrome 58+, Edge 79+, Safari 15.4+, Firefox: nicht Kategorie: webapi

Signatur

RTCTransportStats.selectedCandidatePairId

Beschreibung

Die Eigenschaft selectedCandidatePairId ist ein String im RTCTransportStats-Wörterbuch, also in einem Statistik-Eintrag mit type === "transport". Sie verweist auf die id eines anderen Eintrags im selben RTCStatsReport, nämlich auf das RTCIceCandidatePairStats-Objekt (type === "candidate-pair"), über das der Transport gerade Daten sendet und empfängt.

So findet man zuverlässig heraus, welche Verbindung tatsächlich genutzt wird: Über das Kandidatenpaar gelangt man per localCandidateId und remoteCandidateId zu den lokalen und entfernten Kandidaten und sieht deren Typ (host, srflx, relay). Damit lässt sich etwa erkennen, ob der Datenverkehr über einen TURN-Server läuft, und man kann Werte wie currentRoundTripTime oder availableOutgoingBitrate auslesen.

Solange ICE noch kein Paar ausgewählt hat (z. B. direkt nach dem Verbindungsaufbau oder bei Fehlschlag), fehlt die Eigenschaft oder ist undefined. Nach einem ICE-Restart oder einem Netzwerkwechsel kann sich der Wert ändern. Deshalb sollte man ihn bei jeder Abfrage von getStats() neu auswerten statt ihn zwischenzuspeichern.

Rückgabewert

Typ
string | undefined
Beschreibung
Die id des ausgewählten RTCIceCandidatePairStats-Eintrags im selben Bericht oder undefined, wenn noch kein Paar ausgewählt wurde.

Beispiele

Ausgewähltes Kandidatenpaar ermitteln

// pc ist eine bereits verbundene RTCPeerConnection
const getSelectedPair = async (pc) => {
  const report = await pc.getStats();
  for (const stats of report.values()) {
    if (stats.type === 'transport' && stats.selectedCandidatePairId) {
      return report.get(stats.selectedCandidatePairId);
    }
  }
  return null;
};

const pair = await getSelectedPair(pc);
console.log(pair?.state, pair?.currentRoundTripTime);
succeeded 0.042

Prüfen, ob die Verbindung über TURN läuft

const isRelayed = async (pc) => {
  const report = await pc.getStats();
  const transport = [...report.values()].find((s) => s.type === 'transport');
  if (!transport?.selectedCandidatePairId) return false;

  const pair = report.get(transport.selectedCandidatePairId);
  const local = report.get(pair.localCandidateId);
  const remote = report.get(pair.remoteCandidateId);
  return local.candidateType === 'relay' || remote.candidateType === 'relay';
};

console.log('Über TURN:', await isRelayed(pc));
Über TURN: false

Verbindungsqualität regelmäßig überwachen

const monitor = (pc, intervalMs = 2000) => {
  const timer = setInterval(async () => {
    const report = await pc.getStats();
    report.forEach((s) => {
      if (s.type !== 'transport' || !s.selectedCandidatePairId) return;
      const pair = report.get(s.selectedCandidatePairId);
      const rtt = ((pair.currentRoundTripTime ?? 0) * 1000).toFixed(0);
      const kbps = ((pair.availableOutgoingBitrate ?? 0) / 1000).toFixed(0);
      console.log(`Paar ${pair.id}: RTT ${rtt} ms, ${kbps} kbit/s`);
    });
  }, intervalMs);
  return () => clearInterval(timer);
};

const stopMonitor = monitor(pc);
// später: stopMonitor();
Paar CPabc123_def456: RTT 38 ms, 2450 kbit/s

// Wichtig · Fallstricke

  • Firefox liefert (Stand 2024) keine transport-Statistiken. Dort findet man das aktive Paar über candidate-pair-Einträge mit selected === true (nicht standardisiert) bzw. nominated === true und state === "succeeded". Für browserübergreifenden Code braucht man einen Fallback.
  • Die Eigenschaft kann fehlen, solange ICE noch nicht verbunden ist. Vor dem Zugriff mit ?. oder einer Prüfung absichern.
  • Die ID ist nur innerhalb desselben RTCStatsReport gültig. IDs aus früheren Berichten sollte man nicht wiederverwenden, da sich das Paar nach einem ICE-Restart oder Netzwerkwechsel ändern kann.
  • Bei BUNDLE (Standardfall) gibt es meist nur einen Transport. Ohne BUNDLE oder bei getrenntem RTCP können mehrere transport-Einträge mit unterschiedlichen Paaren vorhanden sein.
  • Datenschutz: Kandidaten-Statistiken können lokale bzw. öffentliche IP-Adressen enthalten. Nicht ungefiltert an Analysedienste senden.