Introduction to WebRTC
Tags: webrtc, react, javascript, webdev
Published: 2021-08-10 07:23:25

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.

![Introduction to WebRTC](https://media.giphy.com/media/5VKbvrjxpVJCM/giphy.gif)

## 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. 
1. The **Peer A create an Offer** in order to communicate with Peer B. 
2. **Peer B need to accept the offer** and send back to the Answer of the Offer.
3. **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.**


```javascript
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.

```javascript
const connection = new RTCPeerConnection();
```

Setting up **ICE candidate Listeners**

```javascript
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.**

```javascript
socket.on("ice-candidate", e => {
    connection.addIceCandidate(JSON.parse(e));
});
```


Step 1: **Peer A Creating and Signalling the Offer** for Peer B.

```javascript
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**

```javascript
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**

```javascript
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.**
```javascript
let DataChannel = Connection.createDataChannel("meeting-chat");
```

**Peer B can listen for that Data Channel**
```javascript
Connection.ondatachannel = e => {
   DataChannel = e.channel
}
```

**Send and Receive Messages**

```javascript 
// 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

```javascript
// 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**  

```javascript
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**
```javascript
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.

```html
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)](https://en.wikipedia.org/wiki/Network_address_translation) 
[STUN](https://en.wikipedia.org/wiki/STUN)
[TURN (Traversal Using Relays Around NAT)] (https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT)
[ICE Candidates](https://en.wikipedia.org/wiki/Interactive_Connectivity_Establishment)
[SDP (Session Description Protocol](https://en.wikipedia.org/wiki/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

![WebRTC Introduction](https://media.giphy.com/media/GB0lKzzxIv1te/giphy.gif)