Start · Sprachen · JavaScript · Referenz · RTCPeerConnection: icegatheringstatechange

RTCPeerConnection: icegatheringstatechange

Ereignis

Wird auf einer <code>RTCPeerConnection</code> ausgelöst, wenn sich <code>iceGatheringState</code> ändert, also der Zustand der ICE-Kandidatensammlung.

seit JavaScript Baseline: alle modernen Browser (Chrome, Edge, Fir Kategorie: webapi

Signatur

peerConnection.addEventListener("icegatheringstatechange", handler)

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

Typ
void
Beschreibung
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);
ICE-Sammlung: gathering ICE-Sammlung: complete

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);
Angebot gesendet: true

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: icegatheringstatechange betrifft nur das Sammeln der Kandidaten. Den Zustand der Verbindung selbst liefern iceconnectionstatechange bzw. connectionstatechange.
  • Das Ende der Sammlung wird zusätzlich durch ein icecandidate-Ereignis mit event.candidate === null angezeigt. Ä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. wrtc oder werift).