Signatur
Beschreibung
Die Eigenschaft packetsSent des Wörterbuchs RTCTransportStats enthält einen fortlaufenden Zähler (eine nicht negative Ganzzahl) aller Pakete, die über den zugrunde liegenden Transport einer RTCPeerConnection verschickt wurden. Gemeint sind die Pakete auf Transportebene (DTLS/ICE, einschließlich RTP, RTCP und Datenkanal-Pakete), nicht nur die Pakete eines einzelnen Medienstroms.
Du bekommst den Wert, indem du RTCPeerConnection.getStats() aufrufst und im zurückgegebenen RTCStatsReport nach Einträgen mit type === "transport" suchst. Da es sich um einen kumulativen Zähler handelt, ist der Wert vor allem im Vergleich zweier Messungen interessant: Aus der Differenz geteilt durch die Zeitdifferenz (timestamp) ergibt sich die Paketrate pro Sekunde.
Typische Einsatzfälle sind Verbindungs-Dashboards, Diagnose-Tools („Kommen überhaupt Daten raus?“) und Qualitätsüberwachung, oft in Kombination mit packetsReceived, bytesSent und bytesReceived.
Rückgabewert
unsigned long long) mit der Gesamtzahl gesendeter Pakete; undefined, wenn der Browser das Feld nicht liefert.Beispiele
Gesendete Pakete des Transports auslesen
const logPacketsSent = async (pc) => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'transport') {
console.log(`Transport ${stats.id}: ${stats.packetsSent ?? 'n/a'} Pakete gesendet`);
}
});
};
// pc ist eine bereits verbundene RTCPeerConnection
await logPacketsSent(pc);
Paketrate pro Sekunde berechnen
const getTransport = async (pc) => {
const report = await pc.getStats();
return [...report.values()].find((s) => s.type === 'transport');
};
let previous = null;
const timer = setInterval(async () => {
const current = await getTransport(pc);
if (!current || current.packetsSent === undefined) return;
if (previous) {
const seconds = (current.timestamp - previous.timestamp) / 1000;
const rate = (current.packetsSent - previous.packetsSent) / seconds;
console.log(`Senderate: ${rate.toFixed(1)} Pakete/s`);
}
previous = current;
}, 1000);
// Aufräumen beim Beenden der Verbindung
pc.addEventListener('connectionstatechange', () => {
if (pc.connectionState === 'closed') clearInterval(timer);
});
Stillstand erkennen
const checkOutgoingTraffic = async (pc, waitMs = 3000) => {
const read = async () => {
const report = await pc.getStats();
const t = [...report.values()].find((s) => s.type === 'transport');
return t?.packetsSent ?? 0;
};
const before = await read();
await new Promise((r) => setTimeout(r, waitMs));
const after = await read();
return after > before;
};
if (!(await checkOutgoingTraffic(pc))) {
console.warn('Es werden keine Pakete mehr gesendet!');
}
// Wichtig · Fallstricke
- Kumulativer Zähler: Der Wert wächst nur; für Raten immer Differenzen zweier Messungen bilden und durch die
timestamp-Differenz teilen. - Transport- vs. Stream-Ebene:
packetsSentzählt alle Pakete des Transports. Für einzelne Medienspuren stattdessenRTCOutboundRtpStreamStats.packetsSent(type === "outbound-rtp") verwenden. - Kompatibilität: Das Feld wurde erst später in die Spezifikation aufgenommen und wird nicht von allen Browsern geliefert (u. a. eingeschränkt in Firefox). Immer auf
undefinedprüfen. - BUNDLE: Bei aktiviertem BUNDLE (Standard) teilen sich meist alle Spuren einen Transport; ohne BUNDLE kann es mehrere
transport-Einträge geben. getStats()nicht zu häufig aufrufen (etwa einmal pro Sekunde genügt), da der Aufruf Rechenaufwand verursacht.