Signatur
Beschreibung
setRemoteDescription() ist ein zentraler Schritt der WebRTC-Aushandlung (Offer/Answer). Die Methode übernimmt die Sitzungsbeschreibung (SDP) des entfernten Peers, also sein Angebot ("offer") oder seine Antwort ("answer"), die meist über einen eigenen Signalisierungskanal wie WebSocket übertragen wird. Erst danach kennt die lokale Verbindung Codecs, Medienspuren, ICE-Parameter und DTLS-Fingerabdrücke des Gegenübers.
Typischer Ablauf: Der Angerufene erhält ein Angebot, ruft setRemoteDescription(offer) auf, erzeugt dann mit createAnswer() eine Antwort und setzt sie mit setLocalDescription(). Der Anrufer ruft setRemoteDescription(answer) auf, sobald die Antwort eintrifft. Danach wechselt signalingState passend (z. B. zu "have-remote-offer" bzw. "stable").
Beim Setzen eines Remote-Angebots werden für neue Medienabschnitte passende RTCRtpTransceiver angelegt, und das Ereignis track wird für eingehende Spuren ausgelöst. Wird ein Angebot gesetzt, während lokal selbst ein Angebot aussteht ("have-local-offer"), führt der Browser automatisch ein Rollback durch. Darauf baut das Muster „Perfect Negotiation“ auf.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $sessionDescription Pflicht | RTCSessionDescriptionInit | RTCSessionDescription | Objekt mit type ("offer", "answer", "pranswer" oder "rollback") und sdp (SDP-Zeichenkette; bei "rollback" nicht nötig). Ein einfaches Objekt reicht, new RTCSessionDescription() ist nicht mehr erforderlich. |
|
| $successCallback / errorCallback | Function | Veraltet: alte Callback-Signatur setRemoteDescription(desc, success, error). Nicht mehr verwenden, sondern das Promise nutzen. |
Rückgabewert
InvalidStateError, InvalidAccessError, OperationError oder RTCError.Beispiele
Angerufener: Angebot übernehmen und beantworten
const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] });
const ws = new WebSocket('wss://signal.example.com');
pc.addEventListener('track', (event) => {
document.querySelector('#remote').srcObject = event.streams[0];
});
ws.addEventListener('message', async ({ data }) => {
const msg = JSON.parse(data);
if (msg.type === 'offer') {
await pc.setRemoteDescription({ type: 'offer', sdp: msg.sdp });
console.log(pc.signalingState);
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
ws.send(JSON.stringify(pc.localDescription));
}
});
Anrufer: Antwort des Gegenübers setzen
const pc = new RTCPeerConnection();
pc.addTransceiver('video');
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
signaling.send(JSON.stringify(pc.localDescription));
signaling.onmessage = async ({ data }) => {
const msg = JSON.parse(data);
if (msg.type === 'answer') {
try {
await pc.setRemoteDescription(msg);
console.log('Aushandlung abgeschlossen:', pc.signalingState);
} catch (err) {
console.error('Ungültige Antwort:', err.name, err.message);
}
}
};
ICE-Kandidaten puffern, bis die Remote-Beschreibung gesetzt ist
const pc = new RTCPeerConnection();
const pendingCandidates = [];
const handleCandidate = async (candidate) => {
if (pc.remoteDescription) {
await pc.addIceCandidate(candidate);
} else {
pendingCandidates.push(candidate); // noch zu früh
}
};
const handleDescription = async (description) => {
await pc.setRemoteDescription(description);
for (const c of pendingCandidates.splice(0)) {
await pc.addIceCandidate(c);
}
console.log('Gepufferte Kandidaten übernommen');
};
// Wichtig · Fallstricke
- Reihenfolge beachten:
addIceCandidate()vorsetRemoteDescription()schlägt mitInvalidStateErrorfehl. Früh eintreffende Kandidaten daher zwischenspeichern. - Zustandsfehler: Eine
"answer"ohne ausstehendes lokales Angebot wird abgelehnt. Bei gleichzeitigen Angeboten beider Seiten („Glare“) hilft das Muster Perfect Negotiation mit implizitem Rollback. - Den Aufruf immer mit
awaitundtry/catchabsichern. Nicht auf das Promise zu warten führt leicht zu Race Conditions mitcreateAnswer(). - Die veraltete Callback-Variante und
new RTCSessionDescription()sind überflüssig. Einfache Objekte{ type, sdp }funktionieren in allen aktuellen Browsern. - Sicherheit: SDP stammt aus einer nicht vertrauenswürdigen Quelle. Den Signalisierungskanal authentifizieren (WSS, Zugriffskontrolle), sonst können Angreifer Verbindungen umleiten. SDP nie ungeprüft in das DOM (
innerHTML) einfügen. - SDP nicht manuell verändern („SDP-Munging“). Das ist fehleranfällig und je nach Browser unterschiedlich unterstützt.
- Die Methode ist in Chrome, Firefox, Safari und Edge verfügbar. WebRTC setzt einen sicheren Kontext (HTTPS) voraus, für Kamera und Mikrofon ist er zwingend.