Start · Sprachen · JavaScript · Referenz · RTCPeerConnection.close()

RTCPeerConnection.close()

Methode

Schließt die aktuelle Peer-Verbindung sofort, beendet alle Transporte und setzt <code>signalingState</code> auf <code>"closed"</code>.

seit JavaScript Baseline: alle modernen Browser Kategorie: webapi

Signatur

RTCPeerConnection.prototype.close()

Beschreibung

Mit close() beendet man eine WebRTC-Verbindung vollständig. Der ICE-Agent stoppt, alle laufenden ICE-Vorgänge werden abgebrochen, und alle Ressourcen wie DTLS-Transporte, SCTP-Assoziation und RTCDataChannel-Instanzen werden freigegeben. Alle Transceiver werden gestoppt.

Der Aufruf läuft synchron ab. Danach hat signalingState den Wert "closed", und auch connectionState bzw. iceConnectionState werden zu "closed". Gleichzeitig feuert die Methode keine connectionstatechange-, iceconnectionstatechange- oder signalingstatechange-Events. Wer beim Beenden etwas aufräumen muss, sollte das deshalb direkt nach dem Aufruf erledigen.

Eine geschlossene Verbindung lässt sich nicht wiederverwenden. Für eine neue Sitzung legt man ein neues RTCPeerConnection-Objekt an. Ein wiederholter Aufruf von close() auf einer schon geschlossenen Verbindung bewirkt nichts und wirft auch keinen Fehler.

Man verwendet close() beim Auflegen eines Anrufs, beim Verlassen einer Seite oder Komponente (z. B. beim Unmount in React oder Vue) und wenn eine Verbindung dauerhaft fehlgeschlagen ist.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined).

Beispiele

Anruf auflegen und lokale Medien freigeben

let pc = new RTCPeerConnection();
let localStream;

const startCall = async () => {
  localStream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
  localStream.getTracks().forEach((track) => pc.addTrack(track, localStream));
};

const hangUp = () => {
  // Kamera und Mikrofon ausschalten – close() stoppt die lokalen Tracks NICHT
  localStream?.getTracks().forEach((track) => track.stop());
  pc.close();
  console.log(pc.signalingState, pc.connectionState);
  pc = null;
};

await startCall();
hangUp();
closed closed

Aufräumen ohne Events – Handler vorher entfernen

const pc = new RTCPeerConnection();

pc.onconnectionstatechange = () => {
  console.log('Neuer Zustand:', pc.connectionState);
};

const cleanup = () => {
  // close() löst connectionstatechange nicht aus – UI selbst aktualisieren
  pc.onicecandidate = null;
  pc.ontrack = null;
  pc.onconnectionstatechange = null;
  pc.close();
  console.log('Verbindung beendet, Zustand:', pc.connectionState);
};

cleanup();
Verbindung beendet, Zustand: closed

Bei dauerhaftem Fehler schließen und neu verbinden

const createConnection = () => {
  const pc = new RTCPeerConnection({
    iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
  });

  pc.addEventListener('connectionstatechange', () => {
    if (pc.connectionState === 'failed') {
      pc.close();
      console.log('Fehlgeschlagen – neue Verbindung wird aufgebaut');
      current = createConnection(); // geschlossene Instanz ist nicht wiederverwendbar
    }
  });

  return pc;
};

let current = createConnection();

Beim Verlassen der Seite schließen

const pc = new RTCPeerConnection();
const channel = pc.createDataChannel('chat');

channel.addEventListener('close', () => console.log('DataChannel geschlossen'));

window.addEventListener('pagehide', () => {
  pc.close(); // schließt auch alle DataChannels
});
DataChannel geschlossen

// Wichtig · Fallstricke

  • Keine Zustands-Events: close() löst weder connectionstatechange noch iceconnectionstatechange oder signalingstatechange aus. Logik, die das Verbindungsende behandelt, muss man deshalb direkt nach dem Aufruf ausführen. Die Gegenstelle bekommt das Ende erst später über ihre eigenen Zustandsänderungen mit (disconnected/failed) oder wenn man ihr über den Signalisierungskanal eine Nachricht schickt (z. B. ein „hangup“).
  • Lokale Tracks laufen weiter: close() stoppt die Tracks aus getUserMedia() nicht. Kamera und Mikrofon bleiben an, bis man track.stop() aufruft.
  • Nicht wiederverwendbar: Nach dem Schließen werfen Methoden wie createOffer(), addTrack() oder setRemoteDescription() einen InvalidStateError. Für eine neue Sitzung braucht man eine neue Instanz.
  • DataChannels: Offene RTCDataChannel-Instanzen werden mit geschlossen. Noch gepufferte Daten (bufferedAmount) können verloren gehen. Wichtige Daten sollte man daher vor dem Schließen vollständig senden.
  • Speicherlecks: Ohne close() hält der Browser Netzwerk-Ressourcen offen. Manche Browser begrenzen außerdem die Zahl gleichzeitiger Peer-Verbindungen, z. B. Chrome auf etwa 500.
  • Kompatibilität: Wird von allen modernen Browsern unterstützt (Chrome, Firefox, Safari, Edge). Ältere Implementierungen haben teilweise noch Events ausgelöst, deshalb sollte man sich nicht darauf verlassen, ob Events kommen oder ausbleiben.