Offer/Answer Trace
The signaling handshake is an ordered sequence of events. This trace breaks down the RTCPeerConnection state machine, showing the exact transitions required to establish a peer-to-peer pipe.
A Common Pitfall
Most WebRTC "connectivity" bugs are actually logic bugs in the signaling layer. If you set the RemoteDescription before the LocalDescription is ready, or if you ignore the onnegotiationneeded event, the browser will throw an InvalidStateError.
The "Happy Path" Transitions
When everything goes right, the signaling state follows a predictable journey between the Offerer (initiator) and the Answerer (receiver).
| Step | Action | Offerer State | Answerer State |
|---|---|---|---|
| 0 | Initial | stable |
stable |
| 1 | Offerer calls setLocalDescription() |
have-local-offer |
stable |
| 2 | Answerer calls setRemoteDescription() |
have-local-offer |
have-remote-offer |
| 3 | Answerer calls setLocalDescription() |
have-local-offer |
stable |
| 4 | Offerer calls setRemoteDescription() |
stable |
stable |
In practice
- Parallel Gathering: Observe how the ICE gathering starts the moment
setLocalDescriptionis called. It does not wait for the peer to respond. - Glare Collisions: If both peers start at Step 1 simultaneously, they enter a "Glare" state. See the State Machine Guide for how to handle this.
- Rollback: If an error occurs during Step 2 or 3, you can call
setLocalDescription({type: "rollback"})to return to thestablestate.
Negotiation can only be initiated when the state is stable. Trying to add a new media track while in have-local-offer will fail. Always queue your changes or wait for the handshake to complete.
Study the JSEP Lifecycle or inspect the SDP Metadata exchanged during this trace.