Start · Sprachen · JavaScript · Referenz · RTCDataChannelStats.timestamp

RTCDataChannelStats.timestamp

Eigenschaft

Ein <code>DOMHighResTimeStamp</code> in Millisekunden, der angibt, wann die Statistikdaten des Datenkanals im <code>RTCDataChannelStats</code>-Objekt erfasst wurden.

seit JavaScript WebRTC-Statistik; unterstützt von Chromium, Firefo Kategorie: webapi

Signatur

RTCDataChannelStats.timestamp

Beschreibung

Die schreibgeschützte Eigenschaft timestamp gibt es in jedem RTCDataChannelStats-Objekt, also in jedem Eintrag vom Typ "data-channel" im RTCStatsReport, den RTCPeerConnection.getStats() zurückgibt. Sie enthält einen DOMHighResTimeStamp, also eine Zeit in Millisekunden (mit Nachkommastellen), zu der der Browser die Werte des Eintrags erfasst hat.

Laut Spezifikation wird die Zeit ab der UNIX-Epoche (1. Januar 1970, UTC) gemessen. Sie lässt sich deshalb ungefähr mit Date.now() oder performance.timeOrigin + performance.now() vergleichen. Wirklich wichtig ist die Eigenschaft aber für Differenzen: Aus zwei Messungen desselben Kanals berechnet man mit timestamp das genaue Zeitintervall. Daraus ergeben sich Kennzahlen wie Bytes pro Sekunde oder Nachrichten pro Sekunde.

Nehmen Sie für solche Rechnungen immer timestamp und nicht die eigene Wartezeit zwischen zwei getStats()-Aufrufen. Der Browser kann Statistiken zwischenspeichern oder verzögert erfassen. Nur timestamp sagt zuverlässig, zu welchem Zeitpunkt die Zähler wie bytesSent, bytesReceived, messagesSent und messagesReceived gemessen wurden.

Rückgabewert

Typ
DOMHighResTimeStamp (number)
Beschreibung
Zeitpunkt der Erfassung in Millisekunden seit der UNIX-Epoche, als Gleitkommazahl.

Beispiele

Zeitstempel der Datenkanal-Statistik auslesen

// Lokale Verbindung mit sich selbst (Loopback) zum Ausprobieren
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
pc1.onicecandidate = (e) => e.candidate && pc2.addIceCandidate(e.candidate);
pc2.onicecandidate = (e) => e.candidate && pc1.addIceCandidate(e.candidate);

const channel = pc1.createDataChannel('chat');
await pc1.setLocalDescription();
await pc2.setRemoteDescription(pc1.localDescription);
await pc2.setLocalDescription();
await pc1.setRemoteDescription(pc2.localDescription);

channel.onopen = async () => {
  channel.send('Hallo');
  const report = await pc1.getStats();
  report.forEach((stats) => {
    if (stats.type === 'data-channel') {
      console.log(stats.label, new Date(stats.timestamp).toISOString());
    }
  });
};
chat 2024-05-14T09:31:12.345Z

Durchsatz eines Datenkanals mit timestamp-Differenzen berechnen

const getChannelStats = async (pc, label) => {
  const report = await pc.getStats();
  for (const stats of report.values()) {
    if (stats.type === 'data-channel' && stats.label === label) return stats;
  }
  return null;
};

const measureThroughput = async (pc, label, intervalMs = 1000) => {
  const before = await getChannelStats(pc, label);
  await new Promise((r) => setTimeout(r, intervalMs));
  const after = await getChannelStats(pc, label);
  if (!before || !after) return null;

  // Genaues Intervall aus den Zeitstempeln, nicht aus intervalMs
  const seconds = (after.timestamp - before.timestamp) / 1000;
  const bytesPerSecond = (after.bytesSent - before.bytesSent) / seconds;
  return Math.round(bytesPerSecond);
};

// Nutzung: const bps = await measureThroughput(pc1, 'chat');
// console.log(`${bps} B/s gesendet`);
48213 B/s gesendet

Alter der Statistikdaten prüfen

const statsAge = async (pc) => {
  const report = await pc.getStats();
  const now = performance.timeOrigin + performance.now();
  return [...report.values()]
    .filter((s) => s.type === 'data-channel')
    .map((s) => ({ label: s.label, ageMs: Math.round(now - s.timestamp) }));
};

// console.table(await statsAge(pc1));
[{ label: 'chat', ageMs: 2 }]

// Wichtig · Fallstricke

  • Nur Differenzen sind wirklich verlässlich: Ältere Browserversionen haben andere Bezugspunkte verwendet, etwa die Zeitbasis von performance.now(). Wenn Sie absolute Zeiten mit Date.now() vergleichen, kann es darum kleine Abweichungen oder Uhrsprünge geben. Differenzen zwischen zwei Messungen desselben Browsers sind dagegen stabil.
  • Zwei Statistikobjekte können denselben timestamp haben, wenn der Browser zwischengespeicherte Werte liefert. Prüfen Sie vor der Division, ob die Differenz 0 ist, sonst entsteht Infinity oder NaN.
  • Der Wert ist eine Gleitkommazahl. Aus Datenschutzgründen (Fingerprinting, Timing-Angriffe) können Browser die Genauigkeit absichtlich verringern.
  • Einträge vom Typ "data-channel" erscheinen im Bericht erst, wenn ein RTCDataChannel angelegt wurde. Ein geschlossener Kanal kann noch eine Zeit lang im Bericht bleiben.
  • Kompatibilität: Chromium-Browser, Firefox und Safari stellen RTCDataChannelStats über getStats() bereit. Welche einzelnen Felder verfügbar sind, kann sich je nach Browser unterscheiden.