Signatur
Beschreibung
Die Eigenschaft bytesDiscardedOnSend des Dictionarys RTCIceCandidatePairStats enthält die Gesamtzahl der Bytes, die für ein bestimmtes ICE-Kandidatenpaar verworfen wurden, weil beim Übergeben der zugehörigen Pakete an den Socket ein Fehler auftrat. Typische Gründe sind ein voller Sendepuffer, zu wenig Speicher oder ein Netzwerkfehler auf Betriebssystemebene. Diese Bytes haben das lokale Gerät also nie verlassen.
Den Wert erhältst du über RTCPeerConnection.getStats(). Im zurückgegebenen RTCStatsReport filterst du nach Einträgen mit type === "candidate-pair". Es handelt sich um einen kumulativen Zähler: Er beginnt bei 0 und steigt während der Lebensdauer des Kandidatenpaars nur an. Aussagekräftig wird er, wenn man die Differenz zwischen zwei Messzeitpunkten betrachtet oder ihn ins Verhältnis zu bytesSent setzt.
In der Praxis dient die Eigenschaft zur Diagnose lokaler Sendeprobleme. Steigt bytesDiscardedOnSend an, liegt das Problem meist nicht im Netzwerk (Paketverlust unterwegs), sondern schon auf dem sendenden Gerät, z. B. bei überlasteten Sockets oder zu hoher Senderate. Zusammen mit packetsDiscardedOnSend lässt sich so genauer eingrenzen, wo Daten verloren gehen.
Rückgabewert
unsigned long long) mit der kumulierten Anzahl der auf diesem Kandidatenpaar verworfenen Bytes. undefined, wenn der Browser die Eigenschaft nicht unterstützt.Beispiele
Verworfene Bytes des aktiven Kandidatenpaars auslesen
// pc ist eine bestehende, verbundene RTCPeerConnection
const logDiscardedBytes = async (pc) => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'candidate-pair' && stats.nominated && stats.state === 'succeeded') {
const discarded = stats.bytesDiscardedOnSend ?? 'nicht unterstützt';
console.log(`Paar ${stats.id}: ${discarded} Bytes verworfen, ${stats.bytesSent} Bytes gesendet`);
}
});
};
await logDiscardedBytes(pc);
Verwerfungsrate pro Intervall überwachen
// Delta zwischen zwei Messungen berechnen, um aktuelle Probleme zu erkennen
const previous = new Map();
const checkDiscardRate = async (pc) => {
const report = await pc.getStats();
for (const stats of report.values()) {
if (stats.type !== 'candidate-pair' || stats.bytesDiscardedOnSend === undefined) continue;
const prev = previous.get(stats.id);
if (prev) {
const discardedDelta = stats.bytesDiscardedOnSend - prev.discarded;
const sentDelta = stats.bytesSent - prev.sent;
if (discardedDelta > 0) {
const ratio = (discardedDelta / (sentDelta + discardedDelta)) * 100;
console.warn(`Socket-Fehler: ${discardedDelta} Bytes verworfen (${ratio.toFixed(2)} %)`);
}
}
previous.set(stats.id, { discarded: stats.bytesDiscardedOnSend, sent: stats.bytesSent });
}
};
const timer = setInterval(() => checkDiscardRate(pc), 2000);
// Später: clearInterval(timer);
Ausgewähltes Kandidatenpaar über den Transport ermitteln
// Das tatsächlich genutzte Paar über selectedCandidatePairId finden
const getSelectedPairStats = async (pc) => {
const report = await pc.getStats();
const transport = [...report.values()].find((s) => s.type === 'transport');
if (!transport?.selectedCandidatePairId) return null;
return report.get(transport.selectedCandidatePairId);
};
const pair = await getSelectedPairStats(pc);
if (pair) {
console.log({
bytesDiscardedOnSend: pair.bytesDiscardedOnSend,
packetsDiscardedOnSend: pair.packetsDiscardedOnSend
});
}
// Wichtig · Fallstricke
- Browser-Kompatibilität: Die Eigenschaft wird derzeit hauptsächlich von Chromium-basierten Browsern (Chrome, Edge, Opera) geliefert. Firefox und Safari stellen sie ggf. nicht bereit – prüfe immer auf
undefined(z. B. mit??), bevor du rechnest, sonst entstehenNaN-Werte. - Kumulativer Zähler: Der Wert wird nie zurückgesetzt. Für die aktuelle Lage einer Verbindung solltest du Differenzen zwischen zwei
getStats()-Aufrufen auswerten. - Kein Netzwerkverlust: Gezählt werden nur Bytes, die lokal beim Schreiben in den Socket verworfen wurden. Paketverlust auf dem Übertragungsweg erscheint hier nicht, sondern z. B. in
RTCRemoteInboundRtpStreamStats.packetsLost. - Mehrere Kandidatenpaare: Ein Report kann viele
candidate-pair-Einträge enthalten. Für aussagekräftige Werte wertest du das überRTCTransportStats.selectedCandidatePairIdausgewählte Paar aus.