Signatur
Beschreibung
Die Eigenschaft type gibt an, welche Art von Statistik-Objekt vorliegt. Jedes Objekt, das RTCPeerConnection.getStats() in einem RTCStatsReport liefert, hat eine type-Eigenschaft. Bei ICE-Kandidaten ist der Wert "local-candidate", wenn der Kandidat vom eigenen Gerät stammt. Kommt er von der Gegenstelle (über die Signalisierung übertragen), ist der Wert "remote-candidate". Beide Varianten haben dieselbe Struktur, nämlich das RTCIceCandidateStats-Wörterbuch.
Man braucht die Eigenschaft vor allem, um aus dem Bericht gezielt die Kandidaten herauszufiltern. Ein RTCStatsReport ist eine Map-ähnliche Sammlung, in der Einträge ganz unterschiedlicher Art gemischt vorkommen, etwa "inbound-rtp", "candidate-pair" oder "transport". Erst mit type erkennt man, welche weiteren Felder ein Eintrag hat, z. B. address, port, protocol oder candidateType.
Typischer Einsatz: Man ermittelt über das aktive "candidate-pair" die Felder localCandidateId und remoteCandidateId und schlägt damit die passenden Kandidaten-Einträge nach. So sieht man, ob eine Verbindung direkt (host), über NAT (srflx/prflx) oder über einen TURN-Server (relay) läuft.
Rückgabewert
RTCIceCandidateStats ist er immer "local-candidate" oder "remote-candidate".Beispiele
Alle lokalen und entfernten Kandidaten auflisten
const listCandidates = async (pc) => {
const report = await pc.getStats();
report.forEach((stat) => {
if (stat.type === 'local-candidate' || stat.type === 'remote-candidate') {
console.log(`${stat.type}: ${stat.candidateType} ${stat.protocol} ${stat.address ?? '(verborgen)'}:${stat.port}`);
}
});
};
// Aufruf, z. B. nachdem die Verbindung aufgebaut ist:
// await listCandidates(peerConnection);
Aktiv genutztes Kandidatenpaar ermitteln (direkt oder über TURN?)
const getActiveRoute = async (pc) => {
const report = await pc.getStats();
let pair;
report.forEach((stat) => {
// Das gewählte Paar hat den Status "succeeded" und ist nominiert
if (stat.type === 'candidate-pair' && stat.nominated && stat.state === 'succeeded') {
pair = stat;
}
});
if (!pair) return null;
const local = report.get(pair.localCandidateId);
const remote = report.get(pair.remoteCandidateId);
console.assert(local.type === 'local-candidate');
console.assert(remote.type === 'remote-candidate');
return {
local: local.candidateType,
remote: remote.candidateType,
viaTurn: local.candidateType === 'relay' || remote.candidateType === 'relay'
};
};
// const route = await getActiveRoute(peerConnection);
// console.log(route);
Kandidaten nach Art zählen
const countCandidates = async (pc) => {
const report = await pc.getStats();
const counts = { 'local-candidate': 0, 'remote-candidate': 0 };
for (const stat of report.values()) {
if (stat.type in counts) counts[stat.type]++;
}
return counts;
};
// console.log(await countCandidates(peerConnection));
// Wichtig · Fallstricke
- Nicht verwechseln:
typegibt die Art des Statistik-Eintrags an ("local-candidate"/"remote-candidate"). Die Art des Kandidaten selbst (host,srflx,prflx,relay) steht incandidateType. - Im Bericht stehen nur Kandidaten, die bis zum Aufruf von
getStats()gesammelt wurden. Wer zu früh abfragt, etwa vor dem Ende des ICE-Gatherings, bekommt eine unvollständige Liste. - Datenschutz: Browser können lokale IP-Adressen durch mDNS-Namen (
*.local) ersetzen oderaddressganz weglassen. Deshalb nie ohne Prüfung auf eine vorhandene Adresse verlassen. - Ältere Chrome-Versionen hatten eine veraltete, callback-basierte
getStats()-Variante mit anderen Typnamen (z. B."localcandidate"ohne Bindestrich). Heute sollte nur die Promise-Variante mit den Namen aus der Spezifikation verwendet werden. - Die Eigenschaft ist nur lesbar. Das Statistik-Objekt ist eine Momentaufnahme und aktualisiert sich nicht von selbst.