Signatur
Beschreibung
Die Eigenschaft responsesReceived ist Teil des Wörterbuchs RTCIceCandidatePairStats, das in einem RTCStatsReport mit type === "candidate-pair" enthalten ist. Sie zählt alle STUN-Antworten auf Verbindungsprüfungen (Binding Responses), die über die Verbindung zwischen dem lokalen und dem entfernten Kandidaten dieses Paares eingegangen sind.
Zusammen mit requestsSent kann man die Qualität und Erreichbarkeit eines Kandidatenpaares einschätzen. Bleibt responsesReceived deutlich hinter requestsSent zurück, gehen Prüfpakete verloren. Häufige Ursachen sind Firewalls, NAT-Probleme oder eine instabile Netzwerkstrecke. Auch nach dem Verbindungsaufbau sendet ICE regelmäßig Prüfanfragen (Consent Freshness, RFC 7675). Der Zähler steigt also während der ganzen Sitzung weiter.
Den Wert liest man über RTCPeerConnection.getStats() aus. Am sinnvollsten ist er für das aktuell ausgewählte Paar. Dieses erkennt man an nominated === true und state === "succeeded" oder über selectedCandidatePairId im transport-Eintrag. Um Verlustraten zu berechnen, liest man den Zähler in festen Abständen aus und vergleicht die Differenzen.
Rückgabewert
Beispiele
Antworten für alle Kandidatenpaare ausgeben
const pc = new RTCPeerConnection();
// ... Signalisierung, Angebot/Antwort und ICE-Austausch ...
const logCandidatePairs = async () => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'candidate-pair') {
console.log(
`${stats.id}: gesendet=${stats.requestsSent}, empfangen=${stats.responsesReceived}, Zustand=${stats.state}`
);
}
});
};
await logCandidatePairs();
Ausgewähltes Paar über den Transport ermitteln
const getSelectedPair = async (pc) => {
const report = await pc.getStats();
let pairId;
report.forEach((s) => {
if (s.type === 'transport' && s.selectedCandidatePairId) {
pairId = s.selectedCandidatePairId;
}
});
return pairId ? report.get(pairId) : undefined;
};
const pair = await getSelectedPair(pc);
if (pair) {
console.log(`STUN-Antworten auf aktivem Pfad: ${pair.responsesReceived}`);
}
Verlustrate der Prüfpakete laufend überwachen
let previous = null;
const monitor = setInterval(async () => {
const report = await pc.getStats();
for (const s of report.values()) {
if (s.type !== 'candidate-pair' || !s.nominated) continue;
if (previous) {
const sent = s.requestsSent - previous.requestsSent;
const received = s.responsesReceived - previous.responsesReceived;
const loss = sent > 0 ? ((sent - received) / sent) * 100 : 0;
console.log(`Prüfpaket-Verlust: ${loss.toFixed(1)} %`);
if (loss > 50) console.warn('Verbindung instabil – ICE-Neustart erwägen');
}
previous = { requestsSent: s.requestsSent, responsesReceived: s.responsesReceived };
}
}, 5000);
// Beim Beenden aufräumen
pc.addEventListener('connectionstatechange', () => {
if (pc.connectionState === 'closed') clearInterval(monitor);
});
// Wichtig · Fallstricke
- Kumulativer Zähler: Der Wert zählt ab Beginn der Sitzung. Für Raten und Verlustquoten muss man Differenzen zwischen zwei Messungen bilden.
- Kein 1:1-Verhältnis: Anfragen, die gerade unterwegs sind, und Neuübertragungen (Retransmissions) sorgen dafür, dass
requestsSentundresponsesReceivedauch bei gesunder Verbindung leicht voneinander abweichen können. - Nicht verwechseln mit
requestsReceivedundresponsesSent. Diese zählen die Prüfungen in die Gegenrichtung, also die, die die Gegenstelle ausgelöst hat. - Browser-Kompatibilität: Die Eigenschaft wird in allen modernen Browsern unterstützt. Ältere Versionen lieferten teils veraltete Report-Typen wie
googCandidatePair(Chrome) oder ließen das Feld weg. Deshalb vor dem Zugriff mittypeof stats.responsesReceived === 'number'prüfen. - Paare, die nie verwendet wurden (Zustand
frozenoderfailed), haben meist den Wert0.