Start · Sprachen · JavaScript · Referenz · RTCIceTransport: statechange

RTCIceTransport: statechange

Ereignis

Wird ausgelöst, wenn sich die Eigenschaft <code>state</code> eines <code>RTCIceTransport</code> ändert, z. B. von <code>"checking"</code> zu <code>"connected"</code> oder <code>"failed"</code>.

seit JavaScript Chromium-Browser und Safari; Firefox erst in neuer Kategorie: webapi

Signatur

iceTransport.addEventListener("statechange", handler)

Beschreibung

Das Ereignis statechange wird an einem RTCIceTransport-Objekt ausgelöst, sobald sich dessen Eigenschaft state ändert. Mögliche Zustände sind "new", "checking", "connected", "completed", "disconnected", "failed" und "closed". Sie beschreiben den Fortschritt der ICE-Verbindungsprüfung (Interactive Connectivity Establishment) für genau diesen Transport.

Anders als RTCPeerConnection.iceConnectionState, das einen über alle Transporte zusammengefassten Zustand liefert, sehen Sie hier den Zustand eines einzelnen Transports. Das ist nützlich, wenn mehrere Transporte parallel laufen (etwa ohne bundlePolicy: "max-bundle") oder wenn Sie Verbindungsdiagnosen pro Medienstrom benötigen.

Den RTCIceTransport erreichen Sie über den DTLS-Transport eines Senders oder Empfängers: sender.transport.iceTransport bzw. receiver.transport.iceTransport. Die Eigenschaft transport ist erst gesetzt, nachdem die Verhandlung (setLocalDescription/setRemoteDescription) begonnen hat – vorher ist sie null.

Registrieren Sie den Handler entweder mit addEventListener("statechange", handler) oder über die Eigenschaft onstatechange. Das Ereignis ist ein einfaches Event, blubbert nicht und ist nicht abbrechbar; den neuen Zustand lesen Sie aus event.target.state.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "statechange".
$handler Pflicht (event: Event) => void Callback, der bei jeder Zustandsänderung aufgerufen wird. event.target ist der RTCIceTransport; der neue Zustand steht in event.target.state.
$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 Handler erhält ein Event-Objekt ohne zusätzliche Eigenschaften.

Beispiele

Zustand des ICE-Transports eines Senders überwachen

const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const sender = pc.addTrack(stream.getAudioTracks()[0], stream);

await pc.setLocalDescription(await pc.createOffer());

// transport ist erst nach setLocalDescription verfügbar
const iceTransport = sender.transport?.iceTransport;

iceTransport?.addEventListener('statechange', (event) => {
  console.log('ICE-Transport-Zustand:', event.target.state);
});
ICE-Transport-Zustand: checking ICE-Transport-Zustand: connected

Auf Verbindungsfehler reagieren und ICE neu starten

const watchIceTransport = (pc, iceTransport) => {
  iceTransport.onstatechange = () => {
    switch (iceTransport.state) {
      case 'disconnected':
        console.warn('Verbindung unterbrochen – warte auf Wiederherstellung …');
        break;
      case 'failed':
        console.error('ICE fehlgeschlagen – starte ICE neu');
        pc.restartIce(); // löst negotiationneeded aus
        break;
      case 'closed':
        console.log('Transport geschlossen');
        iceTransport.onstatechange = null; // Handler entfernen
        break;
    }
  };
};

// Aufruf, sobald der Transport existiert:
// watchIceTransport(pc, pc.getSenders()[0].transport.iceTransport);
ICE fehlgeschlagen – starte ICE neu

Listener mit AbortController wieder entfernen

const controller = new AbortController();
const iceTransport = pc.getReceivers()[0]?.transport?.iceTransport;

iceTransport?.addEventListener('statechange', () => {
  const { state } = iceTransport;
  console.log('Neuer Zustand:', state);
  if (state === 'connected' || state === 'completed') {
    const pair = iceTransport.getSelectedCandidatePair?.();
    console.log('Gewähltes Paar:', pair?.local.type, '→', pair?.remote.type);
    controller.abort(); // Listener entfernen, Diagnose ist fertig
  }
}, { signal: controller.signal });
Neuer Zustand: connected Gewähltes Paar: host → srflx

// Wichtig · Fallstricke

  • Transport erst nach der Verhandlung: RTCRtpSender.transport bzw. RTCRtpReceiver.transport ist vor setLocalDescription/setRemoteDescription null. Prüfen Sie mit optionaler Verkettung (?.), bevor Sie den Listener anhängen.
  • Bündelung: Mit bundlePolicy: "max-bundle" (Standard in modernen Browsern bei gebündelten Angeboten) teilen sich alle Sender und Empfänger denselben RTCIceTransport. Hängen Sie den Listener dann nur einmal an, sonst werden Meldungen doppelt ausgegeben.
  • "disconnected" ist oft nur vorübergehend: Der Zustand kann ohne Eingriff zu "connected" zurückkehren. Starten Sie ICE erst bei "failed" neu (pc.restartIce()), oder warten Sie eine Zeitspanne ab.
  • Browser-Kompatibilität: RTCIceTransport und sein statechange-Ereignis werden von Chromium-Browsern und Safari unterstützt, in Firefox erst in neueren Versionen. Für browserübergreifenden Code bietet sich als Rückfallebene das Ereignis iceconnectionstatechange an RTCPeerConnection an.
  • Nicht mit RTCDtlsTransport-statechange verwechseln: Dieser meldet den Zustand der DTLS-Verschlüsselung über dem ICE-Transport.