Start · Sprachen · JavaScript · Referenz · RTCIceCandidateStats.timestamp

RTCIceCandidateStats.timestamp

Eigenschaft

Gibt als <code>DOMHighResTimeStamp</code> an, wann die Statistikdaten eines lokalen oder entfernten ICE-Kandidaten erfasst wurden.

seit JavaScript Baseline: Chrome, Edge, Firefox, Safari (WebRTC St Kategorie: webapi

Signatur

RTCIceCandidateStats.timestamp

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

Typ
DOMHighResTimeStamp (number)
Beschreibung
Zeitpunkt der Datenerfassung in Millisekunden seit der Unix-Epoche. Der Wert ist schreibgeschützt.

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();
host 192.168.0.12 2024-05-14T09:31:07.412Z srflx 203.0.113.7 2024-05-14T09:31:07.412Z

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));
}
Alter: 3.8 ms Veraltet? false

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);
20 Messpunkte über 8.0 s

// Wichtig · Fallstricke

  • Einheit: Der Wert ist in Millisekunden angegeben, nicht in Sekunden. Für Date kannst 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 mit performance.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 RTCStatsReport denselben 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 DOMHighResTimeStamp je nach Browser und Isolationsstatus (z. B. ohne crossOriginIsolated) 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.