5 minutes
Four browsers sit at one poker table. None of them can reach the others yet. The words peer-to-peer make it sound simple, like two tabs calling each other on the phone. But the browser on your laptop and the browser on a friend's phone each sit behind a router. That router hands out a private address, and the public internet can't reach a private address. So before a card can travel between them, the two browsers have to find each other first. Neither one can do it alone.
WebRTC solves this with a short, fixed introduction. The diagram below shows every step of it.

How two browsers actually connect
It starts with an RTCPeerConnection on each side. This is a built-in browser object, and it owns one direct link to another peer. It gathers addresses, sets up encryption, and carries the traffic. There is one on each browser. Together they form the two ends of the line we are about to draw.
The first browser writes an offer. An offer is an SDP blob. That is plain text that says how to talk to this browser. It lists the codecs the browser supports, its encryption fingerprints, and the addresses where it can be reached. The second browser sends back an answer. The answer is the same kind of description, from its own side. One offer out, one answer back. That pair is the whole negotiation. Once each peer holds the other's description, both know how to build the link.
The hard part is "the addresses where it can be reached." A browser behind a home router only knows its private address, like 192.168.x.x. That address means nothing to anyone outside the home network. To find an address the wider internet can route to, the browser asks a STUN server. A STUN server is a small public service with one job. It replies, "the address I see you coming from is this one." Each address found this way is an ICE candidate, a candidate line tucked into the SDP. ICE stands for Interactive Connectivity Establishment. It means collecting candidates and trying pairs until one of them connects.
The STUN server is the only outside service this connection leans on. In the transport, it is a single line:
From the transport module:
One free Google STUN server is enough to teach two peers their public addresses. No game data ever flows through it.
This leaves one problem. The offer has to reach the second browser before they're connected — that is the reason to send it in the first place. But they can't hand it over the very link they are still trying to build. So both browsers first connect to a server they can already reach: a signaling server. It is not a referee, and it holds no game state. It only relays those first two messages. It sends the offer to the second peer and the answer back to the first. As soon as the answer arrives and the link goes live, signaling is done, and the browsers stop talking to it.
The link finally carries an RTCDataChannel. This is an ordered, low-latency pipe for any bytes you want, opened directly between the two peers. Every fold, every deal, and every hand-sync travels through a DataChannel, browser to browser, with no server in the middle. That direct pipe is what "peer-to-peer" really means, and it exists only after the handshake above.
Continue reading
Unlock the Full Course
Every lesson, the runnable examples, and the finished build — yours to keep.