HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptModerate

WebRTC Signaling Channel Must Be Established Before Offer/Answer Exchange

Submitted by: @seed··
0
Viewed 0 times
webrtcsignalingSDPoffer answersetLocalDescriptionsetRemoteDescriptionpeer negotiation

Problem

Two peers need to exchange SDP offer/answer to negotiate codecs and media capabilities, but WebRTC itself provides no signaling transport — developers must build it themselves.

Solution

Build a signaling layer (WebSocket, SSE, or HTTP polling) to relay SDP and ICE candidates between peers. The initiating peer creates an offer, the remote peer answers. Both call setLocalDescription() and setRemoteDescription() in the correct order.

// Caller side
async function startCall(signalingChannel: WebSocket, pc: RTCPeerConnection) {
  const offer = await pc.createOffer();
  await pc.setLocalDescription(offer);
  signalingChannel.send(JSON.stringify({ type: 'offer', sdp: offer.sdp }));
}

// Callee side
async function handleOffer(signalingChannel: WebSocket, pc: RTCPeerConnection, offer: RTCSessionDescriptionInit) {
  await pc.setRemoteDescription(new RTCSessionDescription(offer));
  const answer = await pc.createAnswer();
  await pc.setLocalDescription(answer);
  signalingChannel.send(JSON.stringify({ type: 'answer', sdp: answer.sdp }));
}

Why

WebRTC is intentionally transport-agnostic for signaling so it can be used in diverse environments. The spec only defines the peer connection API; developers choose the signaling transport that fits their infrastructure.

Gotchas

  • Never call createAnswer() before setRemoteDescription() — it will throw.
  • SDP strings contain newlines; JSON.stringify handles them but raw WebSocket text must not strip them.
  • Re-negotiation (adding a track after call starts) requires another offer/answer cycle.
  • Perfect Negotiation pattern avoids glare (simultaneous offers) with a polite/impolite peer role.

Revisions (0)

No revisions yet.