Signatur
Beschreibung
Die Eigenschaft id des Wörterbuchs RTCIceCandidatePairStats enthält einen String, der das überwachte ICE-Kandidatenpaar eindeutig kennzeichnet. Sie ist von RTCStats geerbt, und jedes Statistikobjekt in einem RTCStatsReport hat eine solche ID.
Die ID ist gleichzeitig der Schlüssel, unter dem das Objekt im RTCStatsReport (einer Map-ähnlichen Struktur) abgelegt ist. Andere Statistikobjekte verweisen über sie auf das Paar. So enthält RTCTransportStats.selectedCandidatePairId genau die id des gerade aktiven Kandidatenpaars. Umgekehrt verweist das Paar mit localCandidateId, remoteCandidateId und transportId auf andere Einträge.
Die ID bleibt über mehrere Aufrufe von getStats() hinweg gleich, solange das Kandidatenpaar existiert. Deshalb eignet sie sich gut, um Messwerte wie bytesSent oder currentRoundTripTime über die Zeit zu verfolgen und daraus Raten zu berechnen.
Rückgabewert
RTCStatsReport eindeutige Kennung des Kandidatenpaars. Das Format ist nicht festgelegt, z. B. "CP4qXv1b2c_Ab3dEf9g" in Chrome.Beispiele
Alle Kandidatenpaare mit ihrer ID auflisten
// pc ist eine bestehende RTCPeerConnection
const listCandidatePairs = async (pc) => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'candidate-pair') {
console.log(`Paar ${stats.id}: Zustand=${stats.state}, nominiert=${stats.nominated}`);
}
});
};
await listCandidatePairs(pc);
Aktives Kandidatenpaar über selectedCandidatePairId finden
const getSelectedPair = async (pc) => {
const report = await pc.getStats();
for (const stats of report.values()) {
if (stats.type === 'transport' && stats.selectedCandidatePairId) {
// Die id dient direkt als Schlüssel im Report
return report.get(stats.selectedCandidatePairId);
}
}
return null;
};
const pair = await getSelectedPair(pc);
if (pair) {
const local = (await pc.getStats()).get(pair.localCandidateId);
console.log(`Aktives Paar ${pair.id}, RTT: ${pair.currentRoundTripTime} s, lokal: ${local?.candidateType}`);
}
Senderate pro Paar über die id verfolgen
const previous = new Map();
const measureBitrate = async (pc) => {
const report = await pc.getStats();
report.forEach((s) => {
if (s.type !== 'candidate-pair') return;
const prev = previous.get(s.id);
if (prev) {
const seconds = (s.timestamp - prev.timestamp) / 1000;
const kbps = ((s.bytesSent - prev.bytesSent) * 8) / seconds / 1000;
console.log(`${s.id}: ${kbps.toFixed(1)} kbit/s`);
}
previous.set(s.id, s);
});
};
const timer = setInterval(() => measureBitrate(pc), 1000);
// später: clearInterval(timer);
// Wichtig · Fallstricke
- Das Format ist nicht festgelegt: Die ID ist ein Browser-internes Detail. Parse sie nicht und speichere sie nicht über Sitzungen hinweg, denn Aufbau und Länge unterscheiden sich zwischen Chrome, Firefox und Safari.
- Nur innerhalb einer Verbindung eindeutig: Die ID ist nur innerhalb der
RTCPeerConnectionund ihres Reports eindeutig. Bei mehreren Verbindungen braucht man einen eigenen Präfix, um Kollisionen zu vermeiden. - Bei einem ICE-Neustart (
restartIce()) oder Netzwerkwechsel können neue Paare mit neuen IDs entstehen. Alte IDs verschwinden dann aus dem Report, deshalb sollten zwischengespeicherte Messwerte aufgeräumt werden. - Ältere Firefox-Versionen kannten
selectedCandidatePairIdnicht. Dort das aktive Paar übernominatedundstate === 'succeeded'bzw. die nicht standardisierte Eigenschaftselectedermitteln. - Die Eigenschaft ist schreibgeschützt. Statistikobjekte sind Momentaufnahmen, für aktuelle Werte muss
getStats()erneut aufgerufen werden.