forked from muaz-khan/WebRTC-Experiment
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWebRTC-Signaling-Concepts.html
More file actions
388 lines (298 loc) · 17.2 KB
/
Copy pathWebRTC-Signaling-Concepts.html
File metadata and controls
388 lines (298 loc) · 17.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
<!--
> Muaz Khan - https://github.com/muaz-khan
> MIT License - https://www.webrtc-experiment.com/licence/
> Experiments - https://github.com/muaz-khan/WebRTC-Experiment
-->
<!DOCTYPE html>
<html id="home" lang="en">
<head>
<title>WebRTC Signaling Concepts ® Muaz Khan</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
<meta name="author" content="Muaz Khan">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link rel="stylesheet" href="https://www.webrtc-experiment.com/style.css">
<style>
p { padding: .8em; }
li {
border-bottom: 1px solid rgb(189, 189, 189);
border-left: 1px solid rgb(189, 189, 189);
padding: .5em;
}
</style>
<!-- for HTML5 el styling -->
<script>
document.createElement('article');
document.createElement('footer');
</script>
<script type="text/javascript" src="https://www.webrtc-experiment.com/syntax/sh_main.min.js"> </script>
<script type="text/javascript" src="https://www.webrtc-experiment.com/syntax/sh_javascript.min.js"> </script>
<script type="text/javascript" src="https://www.webrtc-experiment.com/syntax/sh_html.min.js"> </script>
<link type="text/css" rel="stylesheet" href="https://www.webrtc-experiment.com/syntax/sh_style.css">
</head>
<body onload="sh_highlightDocument();">
<article>
<header style="text-align: center;">
<h1><a href="https://www.webrtc-experiment.com/">WebRTC</a> Signaling Concepts ® <a href="http://www.MuazKhan.com/" target="_blank">Muaz Khan</a></h1>
<p>
<a href="https://www.webrtc-experiment.com/">HOME</a>
<span> © </span>
<a href="http://www.MuazKhan.com/" target="_blank">Muaz Khan</a>
.
<a href="http://twitter.com/WebRTCWeb" target="_blank" title="Twitter profile for WebRTC Experiments">@WebRTCWeb</a>
.
<a href="https://github.com/muaz-khan?tab=repositories" target="_blank" title="Github Profile">Github</a>
.
<a href="https://github.com/muaz-khan/WebRTC-Experiment/issues?state=open" target="_blank">Latest issues</a>
.
<a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">What's New?</a>
</p>
</header>
<div class="github-stargazers"></div>
<blockquote class="inline">
<h2>The term "signaling" in <a href="https://www.webrtc-experiment.com/">WebRTC</a>...</h2>
<p>
Signaling is a process used in <a href="https://www.webrtc-experiment.com/">WebRTC</a> to detect peers; exchange session descriptions to setup media ports; and helps share everything used for initial handshake.
</p>
</blockquote>
<section class="experiment">
<p>
Signaling is used to coordinate communication and send control messages.
</p>
<p>
Signaling is used to exchange session control messages known as SDP; network configurations as ICE candidatess; and media capabilities using same session control messages.
</p>
<p>
Signaling can be done either using copy/paste mechanism; or using a gateway like WebSocket, Socket.io, XMPP or most famous one i.e. session initiation protocol (SIP).
</p>
<p>
You can use the easiest mechanism as well i.e. POST/GET data from a database using XHR.
</p>
<p>
WebRTC signaling process is based on new standard; JSEP: JavaScript Session Establishment Protocol. JSEP is a collection of interfaces for signaling identification; e.g. to identify negotiation of local and remote addresses.
</p>
<p>
Out of JSEP; signaling processs is not left entirely to the application developer. We need to follow the order of the code!
</p>
<h2>How the term "signaling" is used in <a href="https://www.webrtc-experiment.com/">WebRTC Experiments</a>?</h2>
<p>
Approximately all <a href="https://www.webrtc-experiment.com/">WebRTC</a> experiments rely on channels. "Channel" is a term used in realtime protocols like WebSocket to make sure data is transmitted privately over (100%) relevant clients.
</p>
<p>
Channels are created dynamically for each peer; to make sure SDP/ICE is exchanged among relevant users.
</p>
<p>
Just think about "channels" as a "unique-private-room"; the text messages transmitted over that room is accessible inside the room only. Out siders will NEVER ever be able to access those messages.
</p>
<p>
Channels concept is same like "namespaces" concept in socket.io. Namespaces allows you broadcast data over single namespace instead of transmitting publicly.
</p>
<p>
Assume that there are two users; UserA and UserB. <a href="https://www.webrtc-experiment.com/">WebRTC</a> Experiments will setup a new namespace or channel or room; and use it to exchange SDP/ICE/etc. between them. UserA's offer will be shared with UserB using same signaling room; and vice versa.
</p>
<p>
In simplest words; you can consider it "signaling room"; a dynamically opened room used to exchange data between two users. Remember, "Signaling rooms" are unique. So, one can't guess/reach others' signaling rooms, until we manually share room-unique-identifier with him.
</p>
<p>
"Room unique identifier" is a randomly generated number which is used as access key for the room.
</p>
<p>
To share UserA's offer over the room; room-id is used to send/transmit data. UserB i.e. "subscriber" will use same room-id to receive that transmitted data.
</p>
<h2>What about WebSockets which doesn't have concept like "channels"?</h2>
<p>
You just need to use a trick on the server side. Look at this structure:
</p>
<pre class="sh_javascript">
var global_variable_Channels = {
'channel-1': [websocket1, websocket2],
'channel-2': [websocket3, websocket4],
'channel-3': [websocket5, websocket6]
};
</pre>
<p>
On the server side; capture "transmitted messages" like this:
</p>
<pre class="sh_javascript">
var global_variable_Channels = {};
websocket.onmessage = function(e) {
var data = e.data, room;
// if someone asked to open/join a room
if (data.openRoom) {
room = global_variable_Channels[data.roomid];
if (room)
room.push(websocket);
else
room = [websocket];
} else {
// otherwise transmit data over relevant websockets
var message = data.message;
// capture relevant signaling room
room = global_variable_Channels[data.roomid];
if (room == null) throw 'No such signaling-room exists.';
// iterate over all websockets using same room-id
for (var i = 0; i < room.length; i++) {
var websocket = room[i];
// transmit data over those websockets
websocket.send(message);
}
}
};
</pre>
<p>
On the client side; open or join a room like this:
</p>
<pre class="sh_javascript">
websocket.send({
openRoom: true,
roomid: Math.random() * 1000
});
</pre>
<p>
On the client side; you can transmit data like this:
</p>
<pre class="sh_javascript">
websocket.send({
message: 'SDP-or-ICE-etc.',
roomid: 'room-id'
});
</pre>
<h2 id="xhr">What about XHR i.e. POST/GET? <a href="https://github.com/muaz-khan/XHR-Signaling" target="_blank" rel="nofollow">An Example</a></h2>
<p>
Create a table and name it "RoomTable"; add following columns:
</p>
<ol>
<li>Room-id</li>
<li>Owner-id</li>
<li>Participants-id</li>
<li>Message</li>
</ol>
<p>
Create another table and name it "UserTable"; add following columns:
</p>
<ol>
<li>User-id</li>
</ol>
<p>
Now, if someone initiates <a href="https://www.webrtc-experiment.com/">WebRTC</a> session; you should make an XHR request to create a record in the room-table; and set "Owner-id" equals to that user's "user-id".
</p>
<p>
Now, if someone else joins the room; you can update above record; and append his "user-id" in the "Participants-id" column.
</p>
<h2>What if I don't want to use socket.io "namespaces"?</h2>
<p>
Follow process explained for "WebSocket", above.
</p>
<h2>What if I want to use SIP?</h2>
<p>
You don't need to worry about "channels" concept; because you already have "sip-uri". SIP unique identifiers can be used to publish/receive messages privately between two users.
</p>
<h2>Can you compare "channels" with other signaling methods?</h2>
<p>
Channels provide us easiest mechanism to transmit data privately over relevant users. It uses less memory comparing other solutions; and this mechanism is capable to setup unlimited channels without any interrupt.
</p>
<p>
Non-channels based signaling solutions usually stores rooms in an array; same like we did earlier for WebSocket; where you can face memory dump or stack-over-flow issues.
</p>
<p>
Non-channels based signaling is a little bit slower because we need to iterate over the array to find relevant sockets to transmit data.
</p>
<p>
Some "novice" users try to handle all things in the client side; which is NEVER recommended. Because such users transmit all messages publicly, this is easily vulnerable and there are huge chance of failures out of buffer-size and other issues.
</p>
<p>
Remember; NEVER send unneeded messages to a user. Be specific; and keep privacy and make things reliable.
</p>
<h2>What about server-less signaling?</h2>
<p>
You can use copy/paste mechanism to share one user's offer with other; and vice versa.
</p>
<p>
Remember, such things causes delay in setting remote session descriptions for answerer; which may cause failure to setup ports.
</p>
<p>
This mechanism also needs a gateway like Email or IMS to share copied text with other user; who will paste and create answer and so on.
</p>
<h2>What about LAN or intranet?</h2>
<p>
You always need a signaling gateway; whether it installed publicly or privately. A gateway can be a copy/paste mechanism or a realtime protocol.
</p>
<p>
It doesn't matter whether you use custom protocols or topologies for signaling; everything is up to you!
</p>
<p>
Just make it done!
</p>
<h2>What is the difference between ICE server and Signaling server?</h2>
<p>
Signaling is used to detect peers; and exchange prerequisites to setup media connections.
</p>
<p>
ICE which is stands for interactive connectivity establishment is a protocol used to capture public IP addresses of the user. It let us know:
</p>
<ol>
<li>Public IP addresses of the user</li>
<li>It is ipv4 or ipv6</li>
<li>UDP is blocked or not; otherwise fallback to TCP; otherwise fallback to custom protocol.</li>
</ol>
<p>
Some firewalls allow only ports like 443 and 80.
</p>
<p>
So, ICE connectivity establishment is a process used to capture ports and IP addresses and returns "data" back to the browser.
</p>
<p>
<a href="https://www.webrtc-experiment.com/">WebRTC</a> media engines use those ports and public IP addresses to open ports and stream RTP/RTCP packets.
</p>
<p>
RTP contains media packets; and RTCP contains info used to control RTP packets. Both run simultaneously over two unique ports.
</p>
<h2>
Differentiating signaling and ICE:
</h2>
<ol>
<li>Signaling a process is used to detect peers presence; exchange offer/answer between users; as well as exchange ICE candidates.</li>
<li>ICE is a process used to capture public IP addresses and ports of the current user. It NEVER exchanges signaling-data between two users.</li>
<li>There are some ICE servers like TURN that acts as a media gateway in case when Firewall hide public IP addresses of the NAT. RTP/RTCP packets flows from browser to TURN server to other browser.</li>
<li>According to third option; TURN can act as media packets exchanger.</li>
</ol>
<p>
A media packet is an RTP packet contains audio/video/data blobs. Media packets are shared over UDP ports; however signaling packets are shared over HTTP and/or TCP protocols.
</p>
<p>
Remember, media packets i.e. RTP-packets can be shared over TCP protocol as well.
</p>
<h2>Reference: <a href="https://github.com/muaz-khan/WebRTC-Experiment/blob/master/Signaling.md">https://github.com/muaz-khan/WebRTC-Experiment/blob/master/Signaling.md</a></h2>
<ol>
<li><a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/socketio-over-nodejs">Socket.io over Node.js</a></li>
<li><a href="https://github.com/muaz-khan/WebRTC-Experiment/tree/master/websocket-over-nodejs">WebSocket over Node.js</a></li>
</ol>
</section>
<br />
<br />
<section style="border: 1px solid rgb(189, 189, 189); border-radius: .2em; margin: 1em 3em;">
<h2 id="feedback" style="border-bottom: 1px solid rgb(189, 189, 189); padding: .2em .4em;">Feedback</h2>
<div>
<textarea id="message" style="border: 1px solid rgb(189, 189, 189); height: 8em; margin: .2em; outline: none; resize: vertical; width: 98%;" placeholder="Have any message? Suggestions or something went wrong?"></textarea>
</div>
<button id="send-message" style="font-size: 1em;">Send Message</button><small style="margin-left: 1em;">Enter your email too; if you want "direct" reply!</small>
</section>
<section class="experiment own-widgets latest-commits">
<h2 class="header" id="updates" style="color: red; padding-bottom: .1em;"><a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">Latest Updates</a></h2>
<div id="github-commits"></div>
</section>
</article>
<a href="https://github.com/muaz-khan/WebRTC-Experiment" class="fork-left"></a>
<footer>
<p>
<a href="https://www.webrtc-experiment.com/">WebRTC Experiments</a>
© <a href="https://plus.google.com/+MuazKhan" rel="author" target="_blank">Muaz Khan</a>
<a href="mailto:muazkh@gmail.com" target="_blank">muazkh@gmail.com</a>
</p>
</footer>
<!-- commits.js is useless for you! -->
<script src="https://www.webrtc-experiment.com/commits.js" async> </script>
</body>
</html>