Signatur
Beschreibung
Die Eigenschaft messagesSent gehört zum Wörterbuch RTCDataChannelStats. Dieses Wörterbuch ist ein Eintrag vom Typ "data-channel" in dem RTCStatsReport, den RTCPeerConnection.getStats() zurückgibt. Der Wert ist eine nicht negative ganze Zahl und zählt, wie viele Nachrichten die lokale Seite über diesen Datenkanal abgeschickt hat. Jede davon löst beim Empfänger ein message-Ereignis aus.
Jeder Aufruf von RTCDataChannel.send() erhöht den Zähler um eins, egal wie groß die Nachricht ist und ob sie als Zeichenkette, Blob, ArrayBuffer oder ArrayBufferView übergeben wird. Zusammen mit bytesSent lässt sich so die durchschnittliche Nachrichtengröße berechnen. Wenn man die Werte mit messagesReceived auf der Gegenseite vergleicht, lassen sich Verluste oder Staus erkennen. Das ist vor allem bei Kanälen mit ordered: false oder maxRetransmits sinnvoll.
Typische Einsatzgebiete sind Monitoring-Dashboards, Durchsatzmessungen in Multiplayer-Spielen oder bei P2P-Dateiübertragung und die Fehlersuche bei WebRTC-Verbindungen. Weil der Wert kumulativ ist, berechnet man Raten (Nachrichten pro Sekunde) aus der Differenz zweier Messungen und dem Unterschied ihrer timestamp-Werte.
Rückgabewert
unsigned long): Gesamtzahl der bisher über den Datenkanal gesendeten Nachrichten. Fehlt die Eigenschaft im Bericht, ist der Wert undefined.Beispiele
Gesendete Nachrichten aller Datenkanäle auslesen
const pc = new RTCPeerConnection();
const channel = pc.createDataChannel('chat');
const logDataChannelStats = async () => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'data-channel') {
console.log(`${stats.label}: ${stats.messagesSent ?? 0} Nachrichten gesendet`);
}
});
};
channel.addEventListener('open', async () => {
channel.send('Hallo');
channel.send('Welt');
await logDataChannelStats();
});
Senderate in Nachrichten pro Sekunde messen
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 monitorRate = (pc, label, intervalMs = 1000) => {
let previous = null;
return setInterval(async () => {
const current = await getChannelStats(pc, label);
if (!current) return;
if (previous) {
const deltaMsgs = current.messagesSent - previous.messagesSent;
const deltaSec = (current.timestamp - previous.timestamp) / 1000;
console.log(`${label}: ${(deltaMsgs / deltaSec).toFixed(1)} msg/s`);
}
previous = current;
}, intervalMs);
};
// Aufruf: const timer = monitorRate(pc, 'game-state');
// Stoppen: clearInterval(timer);
Durchschnittliche Nachrichtengröße berechnen
const averageMessageSize = async (pc) => {
const report = await pc.getStats();
const result = {};
report.forEach(({ type, label, messagesSent, bytesSent }) => {
if (type === 'data-channel' && messagesSent > 0) {
result[label] = Math.round(bytesSent / messagesSent);
}
});
return result;
};
// console.log(await averageMessageSize(pc));
// Wichtig · Fallstricke
- Zähler ist kumulativ: Der Wert wächst bis zum Ende der Verbindung weiter. Für Raten braucht man zwei Messungen und die Differenz ihrer
timestamp-Werte. - Gesendet heißt nicht zugestellt: Der Zähler steigt schon, wenn die Nachricht angenommen und in den Sendepuffer gelegt wird. Ob sie zugestellt wurde, sagt er nicht. Bei unzuverlässigen Kanälen (
maxRetransmits,maxPacketLifeTime) kannmessagesReceivedauf der Gegenseite kleiner sein. Den Pufferstand zeigtRTCDataChannel.bufferedAmount. - Zuordnung: Die Statistiken zu einem Kanal findet man über
labeloderdataChannelIdentifier(entsprichtRTCDataChannel.id). Labels müssen nicht eindeutig sein. - Kompatibilität: Die Eigenschaft wird in allen aktuellen Browsern unterstützt. Bei älteren Versionen kann sie fehlen. Deshalb defensiv lesen, z. B. mit
stats.messagesSent ?? 0. - Performance:
getStats()ist asynchron und sammelt alle Statistiken der Verbindung. Nicht in sehr kurzen Abständen (unter ca. 250 ms) aufrufen.