Signatur
Beschreibung
Die schreibgeschützte Eigenschaft writable eines RTCIceCandidatePairStats-Objekts gibt an, ob über das beschriebene Kandidatenpaar Daten gesendet werden können. Sie ist true, wenn für das Paar eine Antwort auf eine ICE-Verbindungsprüfung (STUN-Binding-Request) empfangen wurde und die Zustimmung zum Senden (Consent Freshness nach RFC 7675) noch nicht abgelaufen ist.
Das Objekt bekommt man über RTCPeerConnection.getStats(). Im zurückgegebenen RTCStatsReport haben alle Einträge mit type === "candidate-pair" diese Form. Früher hat man writable genutzt, um bei der Fehlersuche zu prüfen, ob ein Pfad zwischen zwei Peers tatsächlich Daten übertragen kann.
Die Eigenschaft ist veraltet und wurde aus der Spezifikation entfernt. In neuem Code solltest du stattdessen state === "succeeded", nominated und responsesReceived auswerten. Zusammen liefern diese Werte dieselbe Aussage.
Rückgabewert
true, wenn die Verbindung beschreibbar ist, sonst false. In Browsern ohne Unterstützung ist der Wert undefined.Beispiele
Beschreibbare Kandidatenpaare auflisten
const listWritablePairs = async (pc) => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'candidate-pair') {
console.log(stats.id, 'writable:', stats.writable);
}
});
};
// pc ist eine bereits verbundene RTCPeerConnection
await listWritablePairs(pc);
Zukunftssicherer Ersatz mit Rückfall
// Nutzt writable, falls vorhanden, sonst standardisierte Felder
const isPairWritable = (pair) => {
if (typeof pair.writable === 'boolean') return pair.writable;
return pair.state === 'succeeded' && (pair.responsesReceived ?? 0) > 0;
};
const getActivePair = async (pc) => {
const report = await pc.getStats();
for (const stats of report.values()) {
if (stats.type === 'candidate-pair' && stats.nominated && isPairWritable(stats)) {
return stats;
}
}
return null;
};
const active = await getActivePair(pc);
console.log(active ? `Aktives Paar: ${active.id}` : 'Kein beschreibbares Paar');
Verbindungsqualität regelmäßig überwachen
const monitor = (pc, intervalMs = 2000) => {
const timer = setInterval(async () => {
const report = await pc.getStats();
const pairs = [...report.values()].filter((s) => s.type === 'candidate-pair');
const writable = pairs.filter((p) => p.writable ?? p.state === 'succeeded');
console.log(`${writable.length}/${pairs.length} Paare beschreibbar`);
}, intervalMs);
// Überwachung beenden, sobald die Verbindung geschlossen wird
pc.addEventListener('connectionstatechange', () => {
if (pc.connectionState === 'closed') clearInterval(timer);
});
};
monitor(pc);
// Wichtig · Fallstricke
- Veraltet und nicht standardisiert:
writableist nicht mehr Teil der W3C-Spezifikation „Identifiers for WebRTC's Statistics API“. Viele aktuelle Browser, darunter Firefox und Safari, liefern die Eigenschaft nicht. Prüfe deshalb immer aufundefined. - Ersatz: Die Kombination aus
state === "succeeded",responsesReceived > 0undnominatedbeschreibt den gleichen Zustand auf standardisierte Weise. - Der Wert ist eine Momentaufnahme. Läuft die Consent-Prüfung ab, zum Beispiel wegen Netzwerkverlust, kann ein Paar wieder nicht beschreibbar werden. Für eine Überwachung musst du
getStats()regelmäßig abfragen. - Frage die Statistiken nicht zu oft ab (Intervalle unter etwa 1 Sekunde).
getStats()ist relativ aufwendig.