Signatur
Beschreibung
Die Eigenschaft currentRoundTripTime eines RTCIceCandidatePairStats-Objekts gibt die zuletzt gemessene Round-Trip-Time an, also die Zeit in Sekunden, die ein Paket vom lokalen zum entfernten Peer und zurück braucht. Gemessen wird sie über STUN-Konnektivitätsprüfungen (Binding-Requests und -Responses) auf genau diesem Kandidatenpaar.
Sie eignet sich gut, um die Verbindungsqualität einer WebRTC-Sitzung zu überwachen, zum Beispiel für Qualitätsanzeigen („Verbindung schwach“), für adaptive Entscheidungen bei Bitrate oder Auflösung oder für Telemetrie. Den Wert bekommt man über RTCPeerConnection.getStats(): Im zurückgegebenen RTCStatsReport sucht man die Einträge mit type === "candidate-pair".
Eine Verbindung kann mehrere Kandidatenpaare haben. Aussagekräftig ist meist nur das aktuell genutzte Paar. Dieses erkennt man über RTCTransportStats.selectedCandidatePairId (Eintrag vom Typ "transport") oder hilfsweise über nominated === true und state === "succeeded". Einen Durchschnittswert berechnet man aus totalRoundTripTime / responsesReceived.
Rückgabewert
0.042 für 42 ms). Die Eigenschaft ist undefined, solange auf diesem Paar noch keine STUN-Antwort eingegangen ist.Beispiele
RTT des aktiven Kandidatenpaares auslesen
const getCurrentRtt = async (pc) => {
const stats = await pc.getStats();
let selectedId;
stats.forEach((report) => {
if (report.type === "transport" && report.selectedCandidatePairId) {
selectedId = report.selectedCandidatePairId;
}
});
const pair = selectedId ? stats.get(selectedId) : undefined;
return pair?.currentRoundTripTime;
};
// pc ist eine verbundene RTCPeerConnection
const rtt = await getCurrentRtt(pc);
if (rtt !== undefined) {
console.log(`Aktuelle RTT: ${(rtt * 1000).toFixed(1)} ms`);
}
Fallback ohne selectedCandidatePairId (z. B. ältere Firefox-Versionen)
const findActivePair = (stats) => {
for (const report of stats.values()) {
if (report.type === "candidate-pair" &&
report.state === "succeeded" &&
(report.nominated || report.selected)) {
return report;
}
}
return null;
};
const stats = await pc.getStats();
const pair = findActivePair(stats);
console.log(pair?.currentRoundTripTime ?? "noch keine Messung");
Verbindungsqualität periodisch überwachen
const qualityLabel = (rttSeconds) => {
if (rttSeconds === undefined) return "unbekannt";
if (rttSeconds < 0.1) return "gut";
if (rttSeconds < 0.3) return "mittel";
return "schlecht";
};
const timer = setInterval(async () => {
const stats = await pc.getStats();
for (const r of stats.values()) {
if (r.type === "candidate-pair" && r.nominated && r.state === "succeeded") {
const avg = r.responsesReceived
? r.totalRoundTripTime / r.responsesReceived
: undefined;
console.log(`aktuell: ${qualityLabel(r.currentRoundTripTime)}, Ø ${avg?.toFixed(3)} s`);
}
}
}, 2000);
pc.addEventListener("connectionstatechange", () => {
if (pc.connectionState === "closed") clearInterval(timer);
});
// Wichtig · Fallstricke
- Einheit ist Sekunden, nicht Millisekunden. Für die Anzeige also mit 1000 multiplizieren.
- Der Wert kann
undefinedsein, etwa direkt nach dem Verbindungsaufbau oder bei Paaren, die nie erfolgreich geprüft wurden. Deshalb immer mit?.oder??absichern. - Die Messung beruht auf STUN-Konnektivitätsprüfungen, nicht auf den Mediendaten. Für die RTT auf RTP/RTCP-Ebene gibt es
RTCRemoteInboundRtpStreamStats.roundTripTime. - Ein einzelner Messwert schwankt stark. Für stabile Aussagen lieber
totalRoundTripTime / responsesReceivednutzen oder selbst glätten. - Browser-Kompatibilität: Chromium und Safari unterstützen die Eigenschaft seit Längerem. Firefox liefert sie erst in neueren Versionen und kennt teils nur das nicht standardisierte
selectedstattselectedCandidatePairId. Deshalb einen Fallback vorsehen, wie im zweiten Beispiel. getStats()ist asynchron und nicht kostenlos. Sehr kurze Abfrageintervalle (unter etwa 500 ms) belasten die CPU unnötig.