WebRTC

Version 31 (Adrian Georgescu, 09/03/2015 10:02 pm)

1 1 Saúl Ibarra Corretgé
h1. SylkServer WebRTC gateway application
2 1 Saúl Ibarra Corretgé
3 31 Adrian Georgescu
Starting with version 3.0.0 SylkServer features WebRTC gateway capabilities. This application implements a WebSocket protocol which WebRTC endpoints can use in order to interact bidirectionally with the SIP world.
4 2 Saúl Ibarra Corretgé
5 24 Adrian Georgescu
h2. Deployment scenarios
6 24 Adrian Georgescu
7 25 Adrian Georgescu
 * Web page calling using a WebRTC enabled web browsers like Firefox and Google Chrome
8 26 Adrian Georgescu
 * Mobile iOS and Android application for multimedia calling
9 24 Adrian Georgescu
10 2 Saúl Ibarra Corretgé
h2. Architecture
11 1 Saúl Ibarra Corretgé
12 25 Adrian Georgescu
SylkServer WebRTC gateway application consists of several (internal and external) components, which together aim to provide the same communication experience as with "Blink":http://icanblink.com or any other feature-full SIP client.
13 21 Saúl Ibarra Corretgé
14 29 Saúl Ibarra Corretgé
<pre>
15 29 Saúl Ibarra Corretgé
+--------+               +-------------+ +----------+     +-------------+
16 29 Saúl Ibarra Corretgé
|        |               |             | |          |     |     SIP     |   
17 29 Saúl Ibarra Corretgé
| WebRTC |  SylkRTC API  |             | |  Janus   +<--->+ audio/video |
18 29 Saúl Ibarra Corretgé
| client +<------------->+  SylkServer | |          |     |    calls    |   
19 29 Saúl Ibarra Corretgé
|        |               |   WebRTC    | +----------+     +-------------+
20 29 Saúl Ibarra Corretgé
+--------+               |   gateway   | +----------+     +-------------+
21 29 Saúl Ibarra Corretgé
                         |             | | Presence |     |   SIMPLE    |   
22 29 Saúl Ibarra Corretgé
                         |             | | and chat +<--->+     IM      |   
23 29 Saúl Ibarra Corretgé
                         |             | | gateway  |     |   Presence  |
24 29 Saúl Ibarra Corretgé
                         +-------------+ +----------+     +-------------+
25 29 Saúl Ibarra Corretgé
</pre>
26 1 Saúl Ibarra Corretgé
27 1 Saúl Ibarra Corretgé
All interaction with the gateway from the Web's side is performed through a WebSocket connection using the "sylkRTC protocol" described in this document.
28 1 Saúl Ibarra Corretgé
29 25 Adrian Georgescu
h5. Registration
30 25 Adrian Georgescu
31 25 Adrian Georgescu
This function is equivalent to SIP REGISTER method and allows an end-point to receive incoming calls.
32 25 Adrian Georgescu
33 1 Saúl Ibarra Corretgé
h5. Audio / video sessions
34 21 Saúl Ibarra Corretgé
35 28 Adrian Georgescu
This function is equivalent to SIP INVITE method and allows an end-point to establish audio and video sessions using RTP protocol. On the web client side DTLS/SRTP encryption is being used. On the SIP side, at the current moment plain RTP is being used, SDES/SRTP being on the roadmap.
36 25 Adrian Georgescu
37 1 Saúl Ibarra Corretgé
Audio and video sessions support is provided through an external component: "Janus.":https://github.com/meetecho/janus-gateway SylkServer communicates directly with Janus and offers a complete API together with the rest of the components described below.
38 21 Saúl Ibarra Corretgé
39 21 Saúl Ibarra Corretgé
h5. Chat sessions
40 1 Saúl Ibarra Corretgé
41 25 Adrian Georgescu
This function is equivalent to SIP INVITE method and allows an end-point to establish chat sessions using MSRP protocol.
42 1 Saúl Ibarra Corretgé
43 21 Saúl Ibarra Corretgé
Chat sessions are implemented as an internal component which translates JSON messages over WebSocket with MSRP chat messages. The payload will remain unchanged, so CPIM is mandatory and will be used end to end. A library such as "cpim.js":https://github.com/eface2face/cpim.js can be used to parse chat messages in a JavaScript application.
44 21 Saúl Ibarra Corretgé
45 25 Adrian Georgescu
h5. Contacts management
46 21 Saúl Ibarra Corretgé
47 25 Adrian Georgescu
This function corresponds to its equivalent XCAP protocol GET/PUT/DELETE methods. Contacts management is implemented as an internal component which fetches the user's XCAP documents and translates the contact list into JSON format, which is then sent over the WebSocket connection.
48 21 Saúl Ibarra Corretgé
49 25 Adrian Georgescu
h5. Presence
50 21 Saúl Ibarra Corretgé
51 21 Saúl Ibarra Corretgé
Presence information is gathered by sending SIP SUBSCRIBE requests on behalf of the user. The presence information is combined with the contact information and provided via JSON events to the application.
52 2 Saúl Ibarra Corretgé
53 2 Saúl Ibarra Corretgé
h2. WebSocket API
54 5 Saúl Ibarra Corretgé
55 1 Saúl Ibarra Corretgé
SylkServer offers the WebSocket API in order to interact with the WebRTC gateway in the @ws(s)://hostname:port/webrtcgateway/ws@ endpoint. Both WebSocket and Secure WebSocket are supported, depending on how SylkServer was configured, check the configuration section.
56 18 Saúl Ibarra Corretgé
57 5 Saúl Ibarra Corretgé
The API uses JSON messages and is modeled around 2 concepts: requests and events. We call this the sylkRTC protocol.
58 5 Saúl Ibarra Corretgé
59 1 Saúl Ibarra Corretgé
A request represents an action which SylkServer should perform, and it's identified with a transaction ID which the user must provide. SylkServer will reply with either an 'ack' or an 'error' response, with the associated transaction ID. An example transaction is that of adding an account.
60 5 Saúl Ibarra Corretgé
61 5 Saúl Ibarra Corretgé
Events are notifications sent by SylkServer to the client. They are the result of some change triggered by a user action, but they don't have a transaction ID associated with them. An example event would be the connection state changed event.
62 1 Saúl Ibarra Corretgé
63 7 Saúl Ibarra Corretgé
All messages are valid JSON and contain the "sylkrtc" key indicating the message type. A message without the "sylkrtc" key is an invalid message.
64 7 Saúl Ibarra Corretgé
65 5 Saúl Ibarra Corretgé
h3. Establishing the connection
66 1 Saúl Ibarra Corretgé
67 25 Adrian Georgescu
In order for a Web application to connect to SylkServer to begin to use the API a WebSocket connection must be established, using the @sylkRTC-1@ subprotocol. Example:
68 6 Saúl Ibarra Corretgé
69 6 Saúl Ibarra Corretgé
<pre>
70 6 Saúl Ibarra Corretgé
var conn = new WebSocket('wss://example.com/webrtcgateway/ws', 'sylkRTC-1');
71 6 Saúl Ibarra Corretgé
</pre>
72 6 Saúl Ibarra Corretgé
73 6 Saúl Ibarra Corretgé
After the connection is established, a 'ready' event will be sent to the client, indicating that the connection is ready to be used:
74 6 Saúl Ibarra Corretgé
75 6 Saúl Ibarra Corretgé
<pre>
76 18 Saúl Ibarra Corretgé
{"event": "ready", "sylkrtc": "event"}
77 6 Saúl Ibarra Corretgé
</pre>
78 1 Saúl Ibarra Corretgé
79 7 Saúl Ibarra Corretgé
Example:
80 7 Saúl Ibarra Corretgé
81 7 Saúl Ibarra Corretgé
<pre>
82 7 Saúl Ibarra Corretgé
var conn = new WebSocket('wss://example.com/webrtcgateway/ws', 'sylkRTC-1');
83 7 Saúl Ibarra Corretgé
conn.onmessage = function(event) {
84 7 Saúl Ibarra Corretgé
    var message = JSON.parse(event.data);
85 7 Saúl Ibarra Corretgé
    switch (message.sylkrtc) {
86 7 Saúl Ibarra Corretgé
        case 'event':
87 7 Saúl Ibarra Corretgé
            if (message.event === 'ready') {
88 7 Saúl Ibarra Corretgé
                console.log('Ready to rock!');
89 7 Saúl Ibarra Corretgé
            }
90 7 Saúl Ibarra Corretgé
            break;
91 1 Saúl Ibarra Corretgé
        default:
92 1 Saúl Ibarra Corretgé
            console.log('Received message type: ' + message.sylkrtc);
93 7 Saúl Ibarra Corretgé
            break;
94 7 Saúl Ibarra Corretgé
    }
95 7 Saúl Ibarra Corretgé
};
96 7 Saúl Ibarra Corretgé
</pre>
97 5 Saúl Ibarra Corretgé
98 18 Saúl Ibarra Corretgé
h3. Account management
99 8 Saúl Ibarra Corretgé
100 25 Adrian Georgescu
Multiple accounts can be managed from a single WebSocket connection. 2 types of requests are used to manage accounts: "account-add" and "account-remove". Once an account has been added it can be registered via SIP using the "account-register" command, and unregistered using the "account-unregister" command. Registration is required for receiving incoming calls. It's not necessary to register an account in order to make outgoing calls.
101 1 Saúl Ibarra Corretgé
102 18 Saúl Ibarra Corretgé
h5. account-add
103 13 Saúl Ibarra Corretgé
104 8 Saúl Ibarra Corretgé
Configures an account on the current connection.
105 8 Saúl Ibarra Corretgé
106 1 Saúl Ibarra Corretgé
<pre>
107 8 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
108 8 Saúl Ibarra Corretgé
 'password': '884edfee38ed471b8a15006700139485',
109 18 Saúl Ibarra Corretgé
 'sylkrtc': 'account-add',
110 8 Saúl Ibarra Corretgé
 'transaction': '04013f0f-25bb-4082-a02f-44399df492ff'}
111 1 Saúl Ibarra Corretgé
</pre>
112 8 Saúl Ibarra Corretgé
113 9 Saúl Ibarra Corretgé
The password MUST be in "HA1 format":https://en.wikipedia.org/wiki/Digest_access_authentication#Overview
114 18 Saúl Ibarra Corretgé
115 1 Saúl Ibarra Corretgé
h5. account-remove
116 9 Saúl Ibarra Corretgé
117 9 Saúl Ibarra Corretgé
Removes an account from the current connection.
118 9 Saúl Ibarra Corretgé
119 8 Saúl Ibarra Corretgé
<pre>
120 1 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
121 18 Saúl Ibarra Corretgé
 'sylkrtc': 'account-remove',
122 9 Saúl Ibarra Corretgé
 'transaction': 'bd3ee25d-5f16-4f76-b34e-8ac3fe0a4ac0'}
123 9 Saúl Ibarra Corretgé
</pre>
124 1 Saúl Ibarra Corretgé
125 13 Saúl Ibarra Corretgé
h5. register
126 1 Saúl Ibarra Corretgé
127 25 Adrian Georgescu
Triggers the account registration via SIP REGISTER method.
128 1 Saúl Ibarra Corretgé
129 9 Saúl Ibarra Corretgé
<pre>
130 9 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
131 18 Saúl Ibarra Corretgé
 'sylkrtc': 'account-register',
132 9 Saúl Ibarra Corretgé
 'transaction': 'bcb87b0f-0cc7-42a9-897e-81f035910670'}
133 9 Saúl Ibarra Corretgé
</pre>
134 9 Saúl Ibarra Corretgé
135 9 Saúl Ibarra Corretgé
The registration progress will be reported in form of events.
136 9 Saúl Ibarra Corretgé
137 9 Saúl Ibarra Corretgé
<pre>
138 9 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
139 9 Saúl Ibarra Corretgé
 'data': {'state': 'registering'},
140 9 Saúl Ibarra Corretgé
 'event': 'registration_state',
141 9 Saúl Ibarra Corretgé
 'sylkrtc': 'account_event'}
142 9 Saúl Ibarra Corretgé
143 9 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
144 9 Saúl Ibarra Corretgé
 'data': {'state': 'registered'},
145 9 Saúl Ibarra Corretgé
 'event': 'registration_state',
146 9 Saúl Ibarra Corretgé
 'sylkrtc': 'account_event'}
147 1 Saúl Ibarra Corretgé
</pre>
148 9 Saúl Ibarra Corretgé
149 9 Saúl Ibarra Corretgé
Example of failed registration:
150 9 Saúl Ibarra Corretgé
151 9 Saúl Ibarra Corretgé
<pre>
152 1 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
153 9 Saúl Ibarra Corretgé
 'data': {'reason': '904 Operation has no matching challenge ',
154 9 Saúl Ibarra Corretgé
          'state': 'failed'},
155 9 Saúl Ibarra Corretgé
 'event': 'registration_state',
156 9 Saúl Ibarra Corretgé
 'sylkrtc': 'account_event'}
157 1 Saúl Ibarra Corretgé
</pre>
158 9 Saúl Ibarra Corretgé
159 18 Saúl Ibarra Corretgé
h5. account-unregister
160 13 Saúl Ibarra Corretgé
161 1 Saúl Ibarra Corretgé
Unregister the account, via SIP.
162 10 Saúl Ibarra Corretgé
163 10 Saúl Ibarra Corretgé
<pre>
164 10 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
165 18 Saúl Ibarra Corretgé
 'sylkrtc': 'account-unregister',
166 1 Saúl Ibarra Corretgé
 'transaction': '1c81eea0-b247-4ced-b3b3-3ced1eba810e'}
167 10 Saúl Ibarra Corretgé
</pre>
168 9 Saúl Ibarra Corretgé
169 18 Saúl Ibarra Corretgé
h3. Sessions
170 1 Saúl Ibarra Corretgé
171 18 Saúl Ibarra Corretgé
h5. Incoming sessions
172 1 Saúl Ibarra Corretgé
173 18 Saúl Ibarra Corretgé
Incoming sessions are received via an *incoming_session* event:
174 14 Saúl Ibarra Corretgé
175 1 Saúl Ibarra Corretgé
<pre>
176 14 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
177 20 Saúl Ibarra Corretgé
 'data': {'originator': '31208005163@ag-projects.com', 'sdp': '...'},
178 18 Saúl Ibarra Corretgé
 'event': 'incoming_session',
179 1 Saúl Ibarra Corretgé
 'session': '509b256aa6a14540a2a37553e6bd33e1',
180 14 Saúl Ibarra Corretgé
 'sylkrtc': 'account_event'}
181 1 Saúl Ibarra Corretgé
182 14 Saúl Ibarra Corretgé
</pre>
183 1 Saúl Ibarra Corretgé
184 18 Saúl Ibarra Corretgé
The "session-answer" request can be used in order to answer an incoming session:
185 1 Saúl Ibarra Corretgé
186 1 Saúl Ibarra Corretgé
<pre>
187 15 Saúl Ibarra Corretgé
{'sdp': '...',
188 15 Saúl Ibarra Corretgé
 'session': '38dffdf81acb44b2b11b61f4488c4ca9',
189 18 Saúl Ibarra Corretgé
 'sylkrtc': 'session-answer',
190 15 Saúl Ibarra Corretgé
 'transaction': '179a855f-75a0-45a4-b5ef-0be8eb8389d1'}
191 1 Saúl Ibarra Corretgé
</pre>
192 15 Saúl Ibarra Corretgé
193 18 Saúl Ibarra Corretgé
h5. Outgoing sessions
194 14 Saúl Ibarra Corretgé
195 18 Saúl Ibarra Corretgé
In order to create an outgoing session the "session-create" request is used, by passing the SDP returned by the web browser. There is no need to wait for all ICE candidates since trickle ICE is used.
196 1 Saúl Ibarra Corretgé
197 14 Saúl Ibarra Corretgé
<pre>
198 14 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
199 14 Saúl Ibarra Corretgé
 'sdp': '...',
200 14 Saúl Ibarra Corretgé
 'session': '20c40185-1ef2-419e-b91a-70415778acb4',
201 18 Saúl Ibarra Corretgé
 'sylkrtc': 'session-create',
202 1 Saúl Ibarra Corretgé
 'transaction': '7afcb91a-8a64-4664-9448-8cb760492e1f',
203 1 Saúl Ibarra Corretgé
 'uri': '3333@sip2sip.info'}
204 14 Saúl Ibarra Corretgé
</pre>
205 14 Saúl Ibarra Corretgé
206 15 Saúl Ibarra Corretgé
h5. Trickle ICE
207 15 Saúl Ibarra Corretgé
208 18 Saúl Ibarra Corretgé
As new candidates are discovered they must be sent to the server using 'session-trickle' requests:
209 14 Saúl Ibarra Corretgé
210 14 Saúl Ibarra Corretgé
<pre>
211 14 Saúl Ibarra Corretgé
{'candidates': [{'candidate': 'candidate:0 1 UDP 2130379007 192.168.99.44 59051 typ host',
212 14 Saúl Ibarra Corretgé
                 'sdpMLineIndex': 0,
213 14 Saúl Ibarra Corretgé
                 'sdpMid': ''}],
214 1 Saúl Ibarra Corretgé
 'session': '20c40185-1ef2-419e-b91a-70415778acb4',
215 18 Saúl Ibarra Corretgé
 'sylkrtc': 'session-trickle',
216 1 Saúl Ibarra Corretgé
 'transaction': 'ecf777d8-7d26-4f16-bace-18f6fae5d8f8'}
217 1 Saúl Ibarra Corretgé
</pre>
218 1 Saúl Ibarra Corretgé
219 19 Saúl Ibarra Corretgé
Use an empty list of candidates to indicate that no more candidates will be sent.
220 19 Saúl Ibarra Corretgé
221 15 Saúl Ibarra Corretgé
This applies to both incoming and outgoing calls.
222 15 Saúl Ibarra Corretgé
223 15 Saúl Ibarra Corretgé
There is no need to wait for the acknowledgement for the "session-create" or "session-answer" request before sending "session-trickle" requests.
224 1 Saúl Ibarra Corretgé
225 19 Saúl Ibarra Corretgé
h5. Terminating sessions
226 15 Saúl Ibarra Corretgé
227 19 Saúl Ibarra Corretgé
A session can be terminated at any time by sending the "session-terminate" request:
228 1 Saúl Ibarra Corretgé
229 15 Saúl Ibarra Corretgé
<pre>
230 15 Saúl Ibarra Corretgé
{'session': '38dffdf81acb44b2b11b61f4488c4ca9',
231 19 Saúl Ibarra Corretgé
 'sylkrtc': 'session-terminate',
232 15 Saúl Ibarra Corretgé
 'transaction': '4d169de8-fe55-41f8-9a5c-c5f66c0a23c7'}
233 1 Saúl Ibarra Corretgé
</pre>
234 15 Saúl Ibarra Corretgé
235 15 Saúl Ibarra Corretgé
h5. Events
236 15 Saúl Ibarra Corretgé
237 19 Saúl Ibarra Corretgé
Session state related events are reported via the "session_event" event:
238 16 Saúl Ibarra Corretgé
239 16 Saúl Ibarra Corretgé
<pre>
240 16 Saúl Ibarra Corretgé
'data': {'state': 'established'},
241 16 Saúl Ibarra Corretgé
 'event': 'state',
242 16 Saúl Ibarra Corretgé
 'session': '38dffdf81acb44b2b11b61f4488c4ca9',
243 16 Saúl Ibarra Corretgé
 'sylkrtc': 'session_event'}
244 16 Saúl Ibarra Corretgé
</pre>
245 16 Saúl Ibarra Corretgé
246 16 Saúl Ibarra Corretgé
<pre>
247 16 Saúl Ibarra Corretgé
{'data': {'sdp': '...', 'state': 'accepted'},
248 16 Saúl Ibarra Corretgé
 'event': 'state',
249 16 Saúl Ibarra Corretgé
 'session': '20c40185-1ef2-419e-b91a-70415778acb4',
250 16 Saúl Ibarra Corretgé
 'sylkrtc': 'session_event'}
251 16 Saúl Ibarra Corretgé
</pre>
252 16 Saúl Ibarra Corretgé
253 1 Saúl Ibarra Corretgé
<pre>
254 1 Saúl Ibarra Corretgé
{'data': {'reason': '200 to BYE', 'state': 'terminated'},
255 1 Saúl Ibarra Corretgé
 'event': 'state',
256 1 Saúl Ibarra Corretgé
 'session': '20c40185-1ef2-419e-b91a-70415778acb4',
257 16 Saúl Ibarra Corretgé
 'sylkrtc': 'session_event'}
258 16 Saúl Ibarra Corretgé
</pre>
259 1 Saúl Ibarra Corretgé
260 19 Saúl Ibarra Corretgé
Valid session states:
261 17 Saúl Ibarra Corretgé
262 19 Saúl Ibarra Corretgé
* incoming: initial state for incoming sessions, no state event is sent for this state.
263 19 Saúl Ibarra Corretgé
* progress: on outgoing sessions, when in progress.
264 19 Saúl Ibarra Corretgé
* accepted: both for incoming and outgoing, when the session has been accepted by the remote party. For incoming, an "sdp" attribute will be present in the "data" section, as shown in the example above. 
265 19 Saúl Ibarra Corretgé
* established: the session has been established media-wise.
266 19 Saúl Ibarra Corretgé
* terminated: session was terminated, the "reason" attribute indicates the termination reason.
267 4 Saúl Ibarra Corretgé
268 25 Adrian Georgescu
h2. Zero-configuration
269 4 Saúl Ibarra Corretgé
270 27 Adrian Georgescu
The server is designed to work without any special configuration, its defaults settings will provide a working environment immediately after starting the software. It is however desirable to replace the bundled test TLS certificate with a valid TLS certificate for a valid hostname found in public DNS and signed by an authority recognised by web applications.
271 2 Saúl Ibarra Corretgé
272 23 Saúl Ibarra Corretgé
h2. JavaScript client library
273 1 Saúl Ibarra Corretgé
274 30 Saúl Ibarra Corretgé
In order to interact with SylkServer's WebRTC gateway, "sylkrtc.js":https://github.com/AGProjects/sylkrtc.js JavaScript library is provided. This library implements the API described in this document in an easy to use manner. Check the README file in the project for the JavaScript API documentation.