Start · Sprachen · JavaScript · Referenz · RTCIceCandidatePairStats.lastPacketReceivedTimestamp

RTCIceCandidatePairStats.lastPacketReceivedTimestamp

Eigenschaft

Zeitstempel (<code>DOMHighResTimeStamp</code>), zu dem über das beschriebene ICE-Kandidatenpaar zuletzt ein Paket empfangen wurde.

seit JavaScript Chrome 80+, Edge 80+, Safari 14.1+; nicht in Firef Kategorie: webapi

Signatur

RTCIceCandidatePairStats.lastPacketReceivedTimestamp

Beschreibung

Die Eigenschaft lastPacketReceivedTimestamp gehört zum Wörterbuch RTCIceCandidatePairStats, also zu den Statistikobjekten vom Typ "candidate-pair". Diese liefert RTCPeerConnection.getStats(). Der Wert ist ein DOMHighResTimeStamp in Millisekunden und gibt an, wann über dieses Kandidatenpaar zuletzt ein Paket empfangen wurde. Gezählt werden Pakete aller Art, also Medien- und Datenpakete ebenso wie STUN-Pakete zur Verbindungsprüfung.

Nützlich ist die Eigenschaft vor allem, um ausbleibende eingehende Pakete zu erkennen. Liegt der Zeitstempel deutlich hinter dem Zeitstempel des Berichts (stats.timestamp), kommt auf diesem Pfad nichts mehr an. Das kann ein Zeichen für einen Netzwerkausfall sein, für einen stummgeschalteten Sender oder für einen bevorstehenden ICE-Neustart.

Wie alle Statistik-Zeitstempel bezieht sich der Wert auf die Performance-Zeitbasis. Vergleichen solltest du ihn deshalb mit stats.timestamp oder performance.now() und nicht mit Date.now(). Wurde noch kein Paket empfangen, fehlt die Eigenschaft meist ganz.

Rückgabewert

Typ
number (DOMHighResTimeStamp) | undefined
Beschreibung
Zeitpunkt des zuletzt empfangenen Pakets in Millisekunden. undefined, wenn noch kein Paket empfangen wurde oder der Browser die Eigenschaft nicht unterstützt.

Beispiele

Letzten Paketempfang des aktiven Kandidatenpaars auslesen

const logLastReceived = async (pc) => {
  const report = await pc.getStats();
  report.forEach((stats) => {
    if (stats.type === 'candidate-pair' && stats.nominated && stats.state === 'succeeded') {
      const ts = stats.lastPacketReceivedTimestamp;
      if (ts === undefined) {
        console.log('Noch kein Paket empfangen oder nicht unterstützt');
        return;
      }
      const ageMs = stats.timestamp - ts;
      console.log(`Letztes Paket vor ${ageMs.toFixed(0)} ms empfangen`);
    }
  });
};

// Aufruf mit einer bestehenden Verbindung:
// await logLastReceived(peerConnection);
Letztes Paket vor 18 ms empfangen

Verbindungsabbruch per Watchdog erkennen

const watchIncoming = (pc, thresholdMs = 3000) => {
  const timer = setInterval(async () => {
    if (pc.connectionState === 'closed') {
      clearInterval(timer);
      return;
    }
    const report = await pc.getStats();
    for (const stats of report.values()) {
      if (stats.type !== 'candidate-pair' || !stats.nominated) continue;
      const last = stats.lastPacketReceivedTimestamp;
      if (last !== undefined && stats.timestamp - last > thresholdMs) {
        console.warn('Seit über 3 s keine Pakete – ICE-Neustart wird eingeleitet');
        pc.restartIce();
      }
    }
  }, 1000);
  return () => clearInterval(timer);
};

// const stopWatch = watchIncoming(peerConnection);
Seit über 3 s keine Pakete – ICE-Neustart wird eingeleitet

Empfang und Versand vergleichen

const compareTraffic = async (pc) => {
  const report = await pc.getStats();
  for (const s of report.values()) {
    if (s.type === 'candidate-pair' && s.nominated) {
      console.table({
        zuletztEmpfangen: s.lastPacketReceivedTimestamp,
        zuletztGesendet: s.lastPacketSentTimestamp,
        bytesEmpfangen: s.bytesReceived,
        bytesGesendet: s.bytesSent
      });
    }
  }
};

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Chromium-Browser und Safari unterstützen die Eigenschaft, Firefox liefert sie derzeit nicht. Prüfe deshalb immer auf undefined.
  • Zeitbasis: Der Wert ist ein DOMHighResTimeStamp. Vergleiche ihn mit stats.timestamp und nicht mit Date.now(), sonst entstehen völlig falsche Differenzen.
  • Richtiges Paar wählen: Ein Bericht kann mehrere candidate-pair-Einträge enthalten. Für den aktiven Pfad filterst du nach nominated und state === "succeeded" oder folgst RTCTransportStats.selectedCandidatePairId.
  • STUN-Verbindungsprüfungen (Keepalives) aktualisieren den Wert ebenfalls. Ein frischer Zeitstempel bedeutet also nicht, dass auch Mediendaten ankommen. Dafür eignen sich RTCInboundRtpStreamStats wie lastPacketReceivedTimestamp oder packetsReceived.
  • getStats() in kurzen Abständen abzufragen kostet CPU. Ein Intervall von 1 s ist für die Überwachung meist ausreichend.