The process you are looking for is called JSEP (JavaScript Session Establishment Protocol), and it can be divided into the three steps described below. These steps begin after both clients are in the room and can communicate via WebSockets, I will use ws as an imaginary WebSocket API for communication between the client and the server and other clients:
1. Invite
At this point, one called party creates and offers and passes it through the server to another client (called):
// This is only in Chrome var pc = new webkitRTCPeerConnection({iceServers:[{url:"stun:stun.l.google.com:19302"}]}, {optional: [{RtpDataChannels: true}]}); // Someone must be chosen to be the caller // (it can be either latest person who joins the room or the people in it) ws.on('joined', function() { var offer = pc.createOffer(function (offer) { pc.setLocalDescription(offer); ws.send('offer', offer); }); }); // The callee receives offer and returns an answer ws.on('offer', function (offer) { pc.setRemoteDescription(new RTCSessionDescription(offer)); pc.createAnswer(function(answer) { pc.setLocalDescription(answer); ws.send('answer', answer); }, err => console.log('error'), {}); }); // The caller receives the answer ws.on('answer', function (answer) { pc.setRemoteDescription(new RTCSessionDescription(answer)); });
Now both sides have exchanged SDP packets and are ready to connect to each other.
2. Negotiations (ICE)
ICE candidates are created on each side to find a way to connect to each other, they have quite a few IP addresses where they can be found: localhost, local network address (192.168.xx) and external public IP address (ISP). They are automatically generated by the PC object.
// Both processing them on each end: ws.on('ICE', candidate => pc.addIceCandidate(new RTCIceCandidate(data))); // Both sending them: pc.onicecandidate = candidate => ws.send('ICE', candidate);
After ICE negotiation, conexion becomes established if you are not trying to connect clients through firewalls on both sides of the connection, p2p communications are NAT bypass, but will not work in some scenarios.
3. Streaming data
// Once the connection is established we can start to transfer video, // audio or data navigator.getUserMedia(function (stream) { pc.addStream(stream); }, err => console.log('Error getting User Media'));
Itβs a good opportunity to have a stream before calling and adding it at an earlier stage, before creating an offer for the calling subscriber and immediately after receiving the call for the called subscriber, so you donβt have to deal with revisions. It was a pain a few years ago, but now it can be better implemented in WebRTC.
Remember to check out my WebRTC project on GitHub, where I create p2p connections in rooms for many participants, it is on GitHub and has a live demo .