Signatur
Beschreibung
Das Ereignis icegatheringstatechange wird auf einer RTCPeerConnection ausgelöst, sobald sich die Eigenschaft iceGatheringState ändert. Sie beschreibt, wie weit der ICE-Agent beim Sammeln von Verbindungskandidaten ist (Host-, STUN- und TURN-Kandidaten). Registrieren lässt sich das Ereignis mit addEventListener("icegatheringstatechange", handler) oder über die Eigenschaft onicegatheringstatechange.
Mögliche Werte von iceGatheringState:
"new": Die Verbindung ist gerade erstellt worden, es wurde noch nicht gesammelt."gathering": Der ICE-Agent sammelt gerade Kandidaten."complete": Die Sammlung ist abgeschlossen. Es kommen erst wieder neue Kandidaten, wenn eine neue Schnittstelle auftaucht oder ein ICE-Neustart ausgelöst wird.
Das Ereignis ist ein einfaches Event ohne zusätzliche Eigenschaften. Den neuen Zustand liest man direkt an pc.iceGatheringState ab. Typischerweise braucht man das für Non-Trickle-ICE: Man wartet mit dem Senden des SDP-Angebots, bis alle Kandidaten gesammelt sind ("complete"). Außerdem eignet es sich für Diagnose und Fortschrittsanzeigen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "icegatheringstatechange". |
|
| $handler Pflicht | (event: Event) => void | Callback, der bei jeder Zustandsänderung aufgerufen wird. Das übergebene Event hat keine eigenen Zusatzdaten. Der Zustand steht in event.target.iceGatheringState. |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once oder signal (zum Entfernen per AbortController). |
Rückgabewert
addEventListener gibt nichts zurück. Der Rückgabewert des Handlers wird ignoriert.Beispiele
Zustandsänderungen protokollieren (addEventListener)
const pc = new RTCPeerConnection({
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
});
pc.addEventListener('icegatheringstatechange', () => {
console.log('ICE-Sammlung:', pc.iceGatheringState);
});
// Sammlung anstoßen: Datenkanal + Angebot erzeugen
pc.createDataChannel('chat');
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
Non-Trickle-ICE: auf vollständige Sammlung warten
const waitForIceGathering = (pc) =>
new Promise((resolve) => {
if (pc.iceGatheringState === 'complete') return resolve();
const onChange = () => {
if (pc.iceGatheringState === 'complete') {
pc.removeEventListener('icegatheringstatechange', onChange);
resolve();
}
};
pc.addEventListener('icegatheringstatechange', onChange);
});
const pc = new RTCPeerConnection();
pc.createDataChannel('data');
await pc.setLocalDescription(await pc.createOffer());
await waitForIceGathering(pc);
// Das SDP enthält jetzt alle Kandidaten
const response = await fetch('/signaling/offer', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(pc.localDescription)
});
console.log('Angebot gesendet:', response.ok);
on-Property mit Fortschrittsanzeige und Zurücksetzen
const pc = new RTCPeerConnection();
const status = document.querySelector('#ice-status');
const labels = {
new: 'Bereit',
gathering: 'Suche Verbindungswege …',
complete: 'Alle Kandidaten gefunden'
};
pc.onicegatheringstatechange = () => {
status.textContent = labels[pc.iceGatheringState];
if (pc.iceGatheringState === 'complete') {
// Handler wieder entfernen
pc.onicegatheringstatechange = null;
}
};
pc.createDataChannel('x');
await pc.setLocalDescription(await pc.createOffer());
// Wichtig · Fallstricke
- Nicht verwechseln:
icegatheringstatechangebetrifft nur das Sammeln der Kandidaten. Den Zustand der Verbindung selbst lieferniceconnectionstatechangebzw.connectionstatechange. - Das Ende der Sammlung wird zusätzlich durch ein
icecandidate-Ereignis mitevent.candidate === nullangezeigt. Ältere Browser haben"complete"nicht immer zuverlässig gemeldet. Für robusten Code prüft man daher beide Signale. - Die Sammlung beginnt erst nach
setLocalDescription(). Ohne Medienspur oder Datenkanal im Angebot werden keine Kandidaten gesammelt. - Bei Non-Trickle-ICE kann das Warten auf
"complete"mehrere Sekunden dauern, etwa bei nicht erreichbaren STUN- oder TURN-Servern. Deshalb sollte man einen Timeout einbauen. Wo es möglich ist, ist Trickle-ICE vorzuziehen. - Nach
restartIce()oder einer Neuverhandlung kann der Zustand wieder auf"gathering"springen. Der Handler darf also nicht davon ausgehen, dass"complete"endgültig ist. - Das Ereignis ist in allen modernen Browsern verfügbar. In Node.js gibt es es nur über Zusatzbibliotheken (z. B.
wrtcoderwerift).