Hey there, I hope you are safe. So today we are going to talk about WebRTC. (Web Real Time Communication)
WebRTC allows you to perform Peer to Peer real-time communication without bothering the Server. Yes, You read it right, You can perform Peer to Peer communication and share media stream like Audio, Video and arbitrary data in real-time.
How do we do that?
So before we can move forward to WebRTC. Let's talk about Socket Connections. Web Sockets allows us to send/receive real-time event at client side that we know that. We established socket connection with Socket Server and then we can broadcast/receive events from/to Server.
We are connected with server. Let's say 2 Clients(Peers) are connected with Server. So, the communication is happening through Server. Server is responsible for that Socket Connection.
because of this reason, peers may sometimes experience of connectivity issue, Message lost and Message delay.
Is that something like Magic?
Hold on, before we send any data to our peer, we need to make a connection and that is a challenging task for developers to established WebRTC connection between two peer.
Signalling
Signalling is the way to exchange information between peers in order to establish connection. This information contains SDP, ICE candidates, User Information etc.
Signalling can be done via Sockets, Real time Database like Firestore etc.
You can always make your signalling Logic to make connection across peers.
How to make Connection? Negotiation
The process start with Making an Offer.
- The Peer A create an Offer in order to communicate with Peer B.
- Peer B need to accept the offer and send back to the Answer of the Offer.
- Peer A accept the Answer.
This process is known as Negotiation.
Negotiation is process in which Peers negotiate about which kind of data they want to exchange (i.e Media Streams, Arbitrary Data) and the best way to exchange that data between two devices.
In general Negotiation let Peers decide what type of Data they want to exchange, before the connection establish between Peers.
SDP (Session Description Protocol)
Offer/Answer is known as SDP (Session Description Protocol). SDP is a format that describe multimedia connections and Sessions across peers. You can assume SDP as ordinary Browser based Sessions.
new RTCPeerConnection().createOffer();
// Output of below code SDP Offer
{
"type": "offer",
"sdp": "v=0\r\no=- 6306366628372337755 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\n"
}
Once the negotiations has been done, Peers can now communicate with each other.
Okay! Show some codes now.
It's time to write some codes. We are going to make WebRTC Connection between Peer A and Peer B.
I am assuming that We are having socket connection between two peer. We are going to use this Sockets as Signalling server.
Creating a global connection object so we can use it later in functions.
const connection = new RTCPeerConnection();
Setting up ICE candidate Listeners
connection.onicecandidate = e => {
// signalling ICE candidates to Peer B whenever we get it.
socket.emit("ice-candidate", JSON.stringify(e.candidate));
}
Adding Ice Candidates to the connection whenever we get over Signalling.
socket.on("ice-candidate", e => {
connection.addIceCandidate(JSON.parse(e));
});
Step 1: Peer A Creating and Signalling the Offer for Peer B.
const makeOffer = async () => {
// creating offer
const offer = await connection.createOffer();
// setting up offer as Peer's Local Description
connection.setLocalDescription(offer);
// signalling offer with Sockets
socket.emit("offer-created", JSON.stringify({ offer });
}
Step 2: Peer B Accepting Offer and Signalling the Answer
const acceptOffer = async (offer) => {
// setting up offer as Remote Description
await connection.setRemoteDescription(new RTCSessionDescription(offer));
// creating answer
const answer = await connection.createAnswer();
// setting up answer as Local Description.
connection.setLocalDescription(answer);
// signalling the answer
socket.emit("answer-added", JSON.stringify({ answer });
}
Step 3: Peer A Saving an Answer
const savingAnswer = async (answer) => {
// lastly, setting up Remote Description of Peer A
await connection.setRemoteDescription(new RTCSessionDescription(answer));
}
Congratulations, You have created Peer to Peer Connection. Now both peer can exchange data with each other.
Throughout this process both connections have shared ICE candidates with each other. That's why we have added Listeners and Signalling whenever we get an ICE candidates.
Exchange Arbitrary data between two peers.
We can create a data channel of connection and then we can send and receive data.
Peer A can create Data Channel.
let DataChannel = Connection.createDataChannel("meeting-chat");
Peer B can listen for that Data Channel
Connection.ondatachannel = e => {
DataChannel = e.channel
}
Send and Receive Messages
// listening for message
DataChannel.onmessage = e => console.log("I got message", e.data);
// sending message
DataChannel.send(JSON.stringify({ message: "Hey Peer" }));
Note: we need to create data channel before peers start communication with each other. Otherwise both peers need to renegotiate.
If peers need to renegotiate, we can listen for that event
// this method can be called anytime if Peers need to
// perform negotiations again.
connection.onnegotiationneeded = e => {
console.log("Please start the negotiation process again");
}
Sending Media Streaming
const sendStream async () => {
if(navigator) {
// browser navigator API to fetch media stream
const stream =
await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
const newStream = new MediaStream();
// sending media tracks to peers
stream.getTracks().forEach((s) => connection.addTrack(s, newStream));
}
}
Receiving Media Streams
connection.ontrack = e => {
// you can use this media stream with <video> tag
console.log("Hey I got Media Streams", e.streams[0]);
}
Debugging
If you are stuck somewhere and want to debug your WebRTC connection, you can debug with in your browser.
brave://webrtc-internals
chrome://webrtc-internals
about:webrtc <!-- For Firefox -->
That's it. That was basic implementation WebRTC connections. Still If you want to know more about WebRTC and How does it works under the hood, You need to understand the network terminologies.
Network Terminologies
NAT (Network Address Translation)
STUN
TURN (Traversal Using Relays Around NAT)
ICE Candidates
SDP (Session Description Protocol
I hope this blog would help you to understand How can you use WebRTC in your next Project.
If you want to add on something, please feel free to leave comment. Also Tell me in the comment section which part did you like most.
Thank you,
Darshan Ponikar
Top comments (6)
Great article, thank you so much for writing! If you enjoy WebRTC, you might also enjoy experimenting with Daily's WebRTC abstraction APIs (full disclosure, I work there): daily.co/
I'll stay tuned for more of your WebRTC articles (just followed you). Great work!
Thank you! I will surely check that link!
Nice article.
Thanks Vishal
Nice article, it would have been nice if you would have also added a working example in a repo
Sure! I am currently working on it and will share the project repo soon.