Signatur
Beschreibung
Die schreibgeschützte Eigenschaft timestamp eines RTCIceCandidateStats-Objekts gibt an, wann die Werte in diesem Statistikobjekt erfasst wurden. Der Wert ist ein DOMHighResTimeStamp, also eine Zahl in Millisekunden (auch mit Nachkommastellen), die laut Spezifikation relativ zur Unix-Epoche (1. Januar 1970, UTC) gemessen wird.
Du bekommst RTCIceCandidateStats-Objekte über RTCPeerConnection.getStats() bzw. RTCRtpSender.getStats()/RTCRtpReceiver.getStats(). Dort haben sie den type "local-candidate" oder "remote-candidate". Der Zeitstempel kommt vom geerbten Wörterbuch RTCStats und ist daher bei allen Statistiktypen gleich aufgebaut.
Nützlich ist timestamp vor allem, wenn du mehrere Messungen vergleichst: Über den Abstand zwischen zwei Zeitstempeln kannst du Raten ausrechnen, Messungen in eine Zeitreihe für Monitoring-Dashboards eintragen oder veraltete Daten erkennen. Mit new Date(stats.timestamp) lässt sich der Wert in ein lesbares Datum umwandeln.
Rückgabewert
Beispiele
Zeitstempel lokaler ICE-Kandidaten auslesen
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.createDataChannel('probe'); // sorgt dafür, dass ICE-Kandidaten gesammelt werden
await pc.setLocalDescription(await pc.createOffer());
// Warten, bis die Kandidatensuche abgeschlossen ist
await new Promise((resolve) => {
if (pc.iceGatheringState === 'complete') return resolve();
pc.addEventListener('icegatheringstatechange', () => {
if (pc.iceGatheringState === 'complete') resolve();
});
});
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'local-candidate') {
console.log(stats.candidateType, stats.address, new Date(stats.timestamp).toISOString());
}
});
pc.close();
Alter eines Statistik-Snapshots prüfen
const isStale = (stats, maxAgeMs = 5000) =>
Date.now() - stats.timestamp > maxAgeMs;
const report = await pc.getStats();
const candidate = [...report.values()].find((s) => s.type === 'remote-candidate');
if (candidate) {
console.log(`Alter: ${(Date.now() - candidate.timestamp).toFixed(1)} ms`);
console.log('Veraltet?', isStale(candidate));
}
Zeitreihe für ein Monitoring aufbauen
const samples = [];
const sampleCandidates = async (pc) => {
const report = await pc.getStats();
for (const s of report.values()) {
if (s.type === 'local-candidate' || s.type === 'remote-candidate') {
samples.push({ id: s.id, type: s.type, at: s.timestamp, candidateType: s.candidateType });
}
}
};
const timer = setInterval(() => sampleCandidates(pc), 2000);
// Nach 10 Sekunden auswerten
setTimeout(() => {
clearInterval(timer);
const first = samples[0]?.at ?? 0;
const last = samples.at(-1)?.at ?? 0;
console.log(`${samples.length} Messpunkte über ${((last - first) / 1000).toFixed(1)} s`);
}, 10000);
// Wichtig · Fallstricke
- Einheit: Der Wert ist in Millisekunden angegeben, nicht in Sekunden. Für
Datekannst du ihn direkt übergeben, bei Unix-Sekunden musst du durch 1000 teilen. - Bezugspunkt: Laut Spezifikation zählt der Wert ab der Unix-Epoche. Er ist also mit
Date.now()bzw.performance.timeOrigin + performance.now()vergleichbar, aber nicht direkt mitperformance.now(). Ältere Browser-Versionen haben hier teilweise andere Zeitbasen genutzt. Rechne deshalb am besten nur mit Differenzen zwischen Zeitstempeln aus demselben Browser. - In der Regel haben alle Einträge eines
RTCStatsReportdenselben oder fast denselben Zeitstempel. Er markiert den Zeitpunkt der Abfrage, nicht den Zeitpunkt, an dem der Kandidat entdeckt wurde. - Zum Schutz vor Fingerprinting kann die Genauigkeit von
DOMHighResTimeStampje nach Browser und Isolationsstatus (z. B. ohnecrossOriginIsolated) reduziert sein. "remote-candidate"-Einträge erscheinen erst, wenn eine Remote-Description gesetzt ist bzw. Kandidaten der Gegenseite eingetroffen sind.- Die Eigenschaft ist schreibgeschützt. Die Statistikobjekte sind Momentaufnahmen und werden nicht automatisch aktualisiert. Für neue Werte rufst du
getStats()erneut auf.