The existing use cases for WebRTC can get really diverse. The most promising spheres:

Google Meet
![]()
WhatsApp
![]()
FB Messenger
![]()
Discord

Network address translation



WebRTC has no protocol for transferring connection data. For this purpose additional server (it is called signalling) is needed:
All data is transmitted as text and is divided into two types - SDP and ICE Candidate.
const peerConnection = new RTCPeerConnection()
const stream = await navigator.getUserMedia({ video: false, audio: true })
for (const track of stream.getTracks()) {
peerConnection.addTrack(track, stream)
}
const description = await this.peerConnection.createOffer()
await peerConnection.setLocalDescription(description)
peerConnection.onicecandidate = event => { /// }
peerConnection.ontrack = event => { /// }
const peerConnection = new RTCPeerConnection()
const stream = await navigator.getUserMedia({ video: false, audio: true })
for (const track of stream.getTracks()) {
peerConnection.addTrack(track, stream)
}
peerConnection.setRemoteDescription(new RTCSessionDescription(remoteDescription))
const description = await this.peerConnection.createAnswer()
await peerConnection.setLocalDescription(description)
peerConnection.onicecandidate = event => { /// }
peerConnection.ontrack = event => { /// }

Microphone
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false })
Microphone and camera
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true })
Screen sharing
const stream = await navigator.mediaDevices.getDisplayMedia()

ICE lets two peers find and establish a connection with one another in such order:
candidate:3511422883 1 udp 2113937151 47e5106c-1c95-4262-b1cd-e917fb8a51b1.local 60843 typ host generation 0 ufrag 3rtW network-cost 999

p1 - [10.50.200.5, 531, udp] - p2
p2 - [10.50.150.3, 531, udp] - p1

p1 - [10.50.200.5, 531, udp] - r1
r1 - [10.50.200.5, 531, udp] - p2
p2 - [10.50.150.3, 531, udp] - r1
r1 - [10.50.150.3, 531, udp] - p1

| Internal IP | Internal PORT | External IP | External PORT |
|---|---|---|---|
| Src IP | Src PORT | Dest IP | Dest PORT |
|---|---|---|---|
| 192.168.0.200 | 35777 | 12.62.100.200 | 6000 |
| Src IP | Src PORT | Dest IP | Dest PORT |
|---|---|---|---|
| 10.50.200.5 | 888 | 12.62.100.200 | 6000 |
r1_nat table
| Internal IP | Internal PORT | External IP | External PORT |
|---|---|---|---|
| 192.168.0.200 | 35777 | 10.50.200.5 | 888 |
| Src IP | Src PORT | Dest IP | Dest PORT |
|---|---|---|---|
| 10.50.200.5 | 888 | 12.62.100.200 | 6000 |
| Src IP | Src PORT | Dest IP | Dest PORT | Content |
|---|---|---|---|---|
| 12.62.100.200 | 6000 | 10.50.200.5 | 888 | 10.50.200.5:888 |
| Internal IP | Internal PORT | External IP | External PORT |
|---|---|---|---|
| 192.168.0.200 | 35777 | 10.50.200.5 | 888 |
| 192.168.0.173 | 35777 | 10.50.200.5 | 889 |
| Src IP | Src PORT | Dest IP | Dest PORT |
|---|---|---|---|
| 12.62.100.200 | 6000 | 192.168.0.200 | 35777 |
TURN advantages:
new RTCPeerConnection({
iceServers: [
{
urls: 'stun:stun.server.com: 13773',
},
{
urls: 'turn:turn.server.com:19403',
username: 'user',
credentials: 'credentials'
}
]
})
{
"channels": 2,
"clockRate": 48000,
"mimeType": "audio/opus",
"payloadType": 111,
"sdpFmtpLine": "minptime=10;useinbandfec=1"
}
{
"clockRate": 90000,
"mimeType": "video/VP8",
"payloadType": 96
}
const senders = peerConnection.getSenders()
for (const sender of senders) {
const params = sender.getParameters()
for (const codec of params.codecs) {
///
}
sender.setParameters(params)
}





const channel = peerConnection.createDataChannel(label, options)
peerConnection.ondatachannel = event => {
const channel = event.channel
}
channel.onmessage = event => {
const data = event.data
}
const data = {
from: id,
date: Date.now(),
message: 'text',
}
channel.send(JSON.stringify(data))
...
channel.onmessage = event => {
const data = JSON.parse(data.event)
}
const file = event.target.files[0]
channel.binaryType = 'arraybuffer'
const arrayBuffer = await file.arrayBuffer()
channel.send(arrayBuffer)
...
channel.onmessage = event => {
const data = event.data
const blob = new Blob([data])
}
npm install webrtc-adapter
import adapter from 'webrtc-adapter'
adapter.browserDetails.browser
adapter.browserDetails.version
offer without streams or data channelif (stream) {
for (const track of stream.getTracks()) {
peerConnection.addTrack(track, stream)
}
} else {
peerConnection.createDataChannel('call')
}
await peerConnection.createOffer()
ice candidates before offerif (peerConnection.remoteDescription) {
await peerConnection.addIceCandidate(new RTCIceCandidate(candidate))
} else {
pendingIceCandidates.push(candidate)
}
///
for (const iceCandidate of pendingIceCandidates) {
await peerConnection.addIceCandidate(new RTCIceCandidate(iceCandidate))
}
pendingIceCandidates = []
streams while the previous negotiation is in progressif (['have-remote-offer', 'stable'].includes(peerConnection.signalingState)) {
for (const track of stream.getTracks()) {
peerConnection.addTrack(track, stream)
}
} else {
pendingStreams.push(stream)
}
Overview of a device's network and media capabilities.

getStats functionpeerConnection.getStats().then(stats => {
for (const report of stats) {
/* [
"RTCAudioSource_2",
{
"id": "RTCAudioSource_2",
"timestamp": 1614698646082.791,
"type": "media-source",
"trackIdentifier": "5a897ba2-630e-453a-b164-d9e193a9391c",
"kind": "audio",
"audioLevel": 0.6677449873348186,
"totalAudioEnergy": 11.904587962536198,
}
] */
}
});

webrtc in name