WebRTC

Version 23 (Saúl Ibarra Corretgé, 07/31/2015 04:19 pm)

1 1 Saúl Ibarra Corretgé
h1. SylkServer WebRTC gateway application
2 1 Saúl Ibarra Corretgé
3 2 Saúl Ibarra Corretgé
Starting with version 3.0.0 SylkServer includes a WebRTC gateway application. The application implements a WebSocket protocol which WebRTC endpoints can use in order to interact with the SIP world.
4 2 Saúl Ibarra Corretgé
5 2 Saúl Ibarra Corretgé
h2. Architecture
6 1 Saúl Ibarra Corretgé
7 21 Saúl Ibarra Corretgé
The SylkServer WebRTC gateway application consists of different (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.
8 21 Saúl Ibarra Corretgé
9 21 Saúl Ibarra Corretgé
TODO: diagram
10 21 Saúl Ibarra Corretgé
11 21 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.
12 21 Saúl Ibarra Corretgé
13 21 Saúl Ibarra Corretgé
h5. Audio / video sessions
14 21 Saúl Ibarra Corretgé
15 21 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.
16 21 Saúl Ibarra Corretgé
17 21 Saúl Ibarra Corretgé
h5. Chat sessions
18 21 Saúl Ibarra Corretgé
19 21 Saúl Ibarra Corretgé
Not implemented yet, consider this an early blueprint.
20 21 Saúl Ibarra Corretgé
21 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.
22 21 Saúl Ibarra Corretgé
23 21 Saúl Ibarra Corretgé
h5. Contacts management and presence
24 21 Saúl Ibarra Corretgé
25 21 Saúl Ibarra Corretgé
Not implemented yet, consider this an early blueprint.
26 21 Saúl Ibarra Corretgé
27 21 Saúl Ibarra Corretgé
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.
28 21 Saúl Ibarra Corretgé
29 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.
30 2 Saúl Ibarra Corretgé
31 2 Saúl Ibarra Corretgé
h2. WebSocket API
32 2 Saúl Ibarra Corretgé
33 5 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.
34 1 Saúl Ibarra Corretgé
35 18 Saúl Ibarra Corretgé
The API uses JSON messages and is modeled around 2 concepts: requests and events. We call this the sylkRTC protocol.
36 5 Saúl Ibarra Corretgé
37 5 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.
38 5 Saúl Ibarra Corretgé
39 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.
40 1 Saúl Ibarra Corretgé
41 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.
42 7 Saúl Ibarra Corretgé
43 5 Saúl Ibarra Corretgé
h3. Establishing the connection
44 1 Saúl Ibarra Corretgé
45 6 Saúl Ibarra Corretgé
In order to connect to SylkServer to begin to use the API a WebSocket connection must be established, using the @sylkRTC-1@ subprotocol. Example:
46 6 Saúl Ibarra Corretgé
47 6 Saúl Ibarra Corretgé
<pre>
48 6 Saúl Ibarra Corretgé
var conn = new WebSocket('wss://example.com/webrtcgateway/ws', 'sylkRTC-1');
49 6 Saúl Ibarra Corretgé
</pre>
50 6 Saúl Ibarra Corretgé
51 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:
52 6 Saúl Ibarra Corretgé
53 6 Saúl Ibarra Corretgé
<pre>
54 18 Saúl Ibarra Corretgé
{"event": "ready", "sylkrtc": "event"}
55 6 Saúl Ibarra Corretgé
</pre>
56 1 Saúl Ibarra Corretgé
57 7 Saúl Ibarra Corretgé
Example:
58 7 Saúl Ibarra Corretgé
59 7 Saúl Ibarra Corretgé
<pre>
60 7 Saúl Ibarra Corretgé
var conn = new WebSocket('wss://example.com/webrtcgateway/ws', 'sylkRTC-1');
61 7 Saúl Ibarra Corretgé
conn.onmessage = function(event) {
62 7 Saúl Ibarra Corretgé
    var message = JSON.parse(event.data);
63 7 Saúl Ibarra Corretgé
    switch (message.sylkrtc) {
64 7 Saúl Ibarra Corretgé
        case 'event':
65 7 Saúl Ibarra Corretgé
            if (message.event === 'ready') {
66 7 Saúl Ibarra Corretgé
                console.log('Ready to rock!');
67 7 Saúl Ibarra Corretgé
            }
68 7 Saúl Ibarra Corretgé
            break;
69 7 Saúl Ibarra Corretgé
        default:
70 7 Saúl Ibarra Corretgé
            console.log('Received message type: ' + message.sylkrtc);
71 7 Saúl Ibarra Corretgé
            break;
72 1 Saúl Ibarra Corretgé
    }
73 7 Saúl Ibarra Corretgé
};
74 7 Saúl Ibarra Corretgé
</pre>
75 7 Saúl Ibarra Corretgé
76 7 Saúl Ibarra Corretgé
h3. Account management
77 5 Saúl Ibarra Corretgé
78 18 Saúl Ibarra Corretgé
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.
79 8 Saúl Ibarra Corretgé
80 10 Saúl Ibarra Corretgé
Note: it's not necessary to register an account in order to make outgoing calls.
81 1 Saúl Ibarra Corretgé
82 18 Saúl Ibarra Corretgé
h5. account-add
83 13 Saúl Ibarra Corretgé
84 8 Saúl Ibarra Corretgé
Configures an account on the current connection.
85 8 Saúl Ibarra Corretgé
86 1 Saúl Ibarra Corretgé
<pre>
87 8 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
88 8 Saúl Ibarra Corretgé
 'password': '884edfee38ed471b8a15006700139485',
89 18 Saúl Ibarra Corretgé
 'sylkrtc': 'account-add',
90 8 Saúl Ibarra Corretgé
 'transaction': '04013f0f-25bb-4082-a02f-44399df492ff'}
91 1 Saúl Ibarra Corretgé
</pre>
92 8 Saúl Ibarra Corretgé
93 8 Saúl Ibarra Corretgé
The password MUST be in "HA1 format":https://en.wikipedia.org/wiki/Digest_access_authentication#Overview
94 9 Saúl Ibarra Corretgé
95 18 Saúl Ibarra Corretgé
h5. account-remove
96 9 Saúl Ibarra Corretgé
97 9 Saúl Ibarra Corretgé
Removes an account from the current connection.
98 9 Saúl Ibarra Corretgé
99 8 Saúl Ibarra Corretgé
<pre>
100 1 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
101 18 Saúl Ibarra Corretgé
 'sylkrtc': 'account-remove',
102 9 Saúl Ibarra Corretgé
 'transaction': 'bd3ee25d-5f16-4f76-b34e-8ac3fe0a4ac0'}
103 9 Saúl Ibarra Corretgé
</pre>
104 1 Saúl Ibarra Corretgé
105 13 Saúl Ibarra Corretgé
h5. register
106 1 Saúl Ibarra Corretgé
107 9 Saúl Ibarra Corretgé
Triggers the account registration via SIP.
108 1 Saúl Ibarra Corretgé
109 9 Saúl Ibarra Corretgé
<pre>
110 9 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
111 18 Saúl Ibarra Corretgé
 'sylkrtc': 'account-register',
112 9 Saúl Ibarra Corretgé
 'transaction': 'bcb87b0f-0cc7-42a9-897e-81f035910670'}
113 9 Saúl Ibarra Corretgé
</pre>
114 9 Saúl Ibarra Corretgé
115 9 Saúl Ibarra Corretgé
The registration progress will be reported in form of events.
116 9 Saúl Ibarra Corretgé
117 9 Saúl Ibarra Corretgé
<pre>
118 9 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
119 9 Saúl Ibarra Corretgé
 'data': {'state': 'registering'},
120 9 Saúl Ibarra Corretgé
 'event': 'registration_state',
121 9 Saúl Ibarra Corretgé
 'sylkrtc': 'account_event'}
122 9 Saúl Ibarra Corretgé
123 9 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
124 9 Saúl Ibarra Corretgé
 'data': {'state': 'registered'},
125 9 Saúl Ibarra Corretgé
 'event': 'registration_state',
126 9 Saúl Ibarra Corretgé
 'sylkrtc': 'account_event'}
127 1 Saúl Ibarra Corretgé
</pre>
128 9 Saúl Ibarra Corretgé
129 9 Saúl Ibarra Corretgé
Example of failed registration:
130 9 Saúl Ibarra Corretgé
131 9 Saúl Ibarra Corretgé
<pre>
132 1 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
133 9 Saúl Ibarra Corretgé
 'data': {'reason': '904 Operation has no matching challenge ',
134 9 Saúl Ibarra Corretgé
          'state': 'failed'},
135 9 Saúl Ibarra Corretgé
 'event': 'registration_state',
136 9 Saúl Ibarra Corretgé
 'sylkrtc': 'account_event'}
137 1 Saúl Ibarra Corretgé
</pre>
138 9 Saúl Ibarra Corretgé
139 18 Saúl Ibarra Corretgé
h5. account-unregister
140 13 Saúl Ibarra Corretgé
141 1 Saúl Ibarra Corretgé
Unregister the account, via SIP.
142 10 Saúl Ibarra Corretgé
143 10 Saúl Ibarra Corretgé
<pre>
144 10 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
145 18 Saúl Ibarra Corretgé
 'sylkrtc': 'account-unregister',
146 1 Saúl Ibarra Corretgé
 'transaction': '1c81eea0-b247-4ced-b3b3-3ced1eba810e'}
147 10 Saúl Ibarra Corretgé
</pre>
148 9 Saúl Ibarra Corretgé
149 18 Saúl Ibarra Corretgé
h3. Sessions
150 1 Saúl Ibarra Corretgé
151 18 Saúl Ibarra Corretgé
h5. Incoming sessions
152 1 Saúl Ibarra Corretgé
153 18 Saúl Ibarra Corretgé
Incoming sessions are received via an *incoming_session* event:
154 14 Saúl Ibarra Corretgé
155 1 Saúl Ibarra Corretgé
<pre>
156 14 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
157 20 Saúl Ibarra Corretgé
 'data': {'originator': '31208005163@ag-projects.com', 'sdp': '...'},
158 18 Saúl Ibarra Corretgé
 'event': 'incoming_session',
159 1 Saúl Ibarra Corretgé
 'session': '509b256aa6a14540a2a37553e6bd33e1',
160 14 Saúl Ibarra Corretgé
 'sylkrtc': 'account_event'}
161 1 Saúl Ibarra Corretgé
162 14 Saúl Ibarra Corretgé
</pre>
163 1 Saúl Ibarra Corretgé
164 18 Saúl Ibarra Corretgé
The "session-answer" request can be used in order to answer an incoming session:
165 1 Saúl Ibarra Corretgé
166 1 Saúl Ibarra Corretgé
<pre>
167 15 Saúl Ibarra Corretgé
{'sdp': '...',
168 15 Saúl Ibarra Corretgé
 'session': '38dffdf81acb44b2b11b61f4488c4ca9',
169 18 Saúl Ibarra Corretgé
 'sylkrtc': 'session-answer',
170 15 Saúl Ibarra Corretgé
 'transaction': '179a855f-75a0-45a4-b5ef-0be8eb8389d1'}
171 1 Saúl Ibarra Corretgé
</pre>
172 15 Saúl Ibarra Corretgé
173 18 Saúl Ibarra Corretgé
h5. Outgoing sessions
174 14 Saúl Ibarra Corretgé
175 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.
176 1 Saúl Ibarra Corretgé
177 14 Saúl Ibarra Corretgé
<pre>
178 14 Saúl Ibarra Corretgé
{'account': 'saghul@sip2sip.info',
179 14 Saúl Ibarra Corretgé
 'sdp': '...',
180 14 Saúl Ibarra Corretgé
 'session': '20c40185-1ef2-419e-b91a-70415778acb4',
181 18 Saúl Ibarra Corretgé
 'sylkrtc': 'session-create',
182 1 Saúl Ibarra Corretgé
 'transaction': '7afcb91a-8a64-4664-9448-8cb760492e1f',
183 1 Saúl Ibarra Corretgé
 'uri': '3333@sip2sip.info'}
184 14 Saúl Ibarra Corretgé
</pre>
185 14 Saúl Ibarra Corretgé
186 15 Saúl Ibarra Corretgé
h5. Trickle ICE
187 15 Saúl Ibarra Corretgé
188 18 Saúl Ibarra Corretgé
As new candidates are discovered they must be sent to the server using 'session-trickle' requests:
189 14 Saúl Ibarra Corretgé
190 14 Saúl Ibarra Corretgé
<pre>
191 14 Saúl Ibarra Corretgé
{'candidates': [{'candidate': 'candidate:0 1 UDP 2130379007 192.168.99.44 59051 typ host',
192 14 Saúl Ibarra Corretgé
                 'sdpMLineIndex': 0,
193 14 Saúl Ibarra Corretgé
                 'sdpMid': ''}],
194 1 Saúl Ibarra Corretgé
 'session': '20c40185-1ef2-419e-b91a-70415778acb4',
195 18 Saúl Ibarra Corretgé
 'sylkrtc': 'session-trickle',
196 1 Saúl Ibarra Corretgé
 'transaction': 'ecf777d8-7d26-4f16-bace-18f6fae5d8f8'}
197 1 Saúl Ibarra Corretgé
</pre>
198 1 Saúl Ibarra Corretgé
199 19 Saúl Ibarra Corretgé
Use an empty list of candidates to indicate that no more candidates will be sent.
200 19 Saúl Ibarra Corretgé
201 15 Saúl Ibarra Corretgé
This applies to both incoming and outgoing calls.
202 15 Saúl Ibarra Corretgé
203 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.
204 1 Saúl Ibarra Corretgé
205 19 Saúl Ibarra Corretgé
h5. Terminating sessions
206 15 Saúl Ibarra Corretgé
207 19 Saúl Ibarra Corretgé
A session can be terminated at any time by sending the "session-terminate" request:
208 1 Saúl Ibarra Corretgé
209 15 Saúl Ibarra Corretgé
<pre>
210 15 Saúl Ibarra Corretgé
{'session': '38dffdf81acb44b2b11b61f4488c4ca9',
211 19 Saúl Ibarra Corretgé
 'sylkrtc': 'session-terminate',
212 15 Saúl Ibarra Corretgé
 'transaction': '4d169de8-fe55-41f8-9a5c-c5f66c0a23c7'}
213 1 Saúl Ibarra Corretgé
</pre>
214 15 Saúl Ibarra Corretgé
215 15 Saúl Ibarra Corretgé
h5. Events
216 15 Saúl Ibarra Corretgé
217 19 Saúl Ibarra Corretgé
Session state related events are reported via the "session_event" event:
218 16 Saúl Ibarra Corretgé
219 16 Saúl Ibarra Corretgé
<pre>
220 16 Saúl Ibarra Corretgé
'data': {'state': 'established'},
221 16 Saúl Ibarra Corretgé
 'event': 'state',
222 16 Saúl Ibarra Corretgé
 'session': '38dffdf81acb44b2b11b61f4488c4ca9',
223 16 Saúl Ibarra Corretgé
 'sylkrtc': 'session_event'}
224 16 Saúl Ibarra Corretgé
</pre>
225 16 Saúl Ibarra Corretgé
226 16 Saúl Ibarra Corretgé
<pre>
227 16 Saúl Ibarra Corretgé
{'data': {'sdp': '...', 'state': 'accepted'},
228 16 Saúl Ibarra Corretgé
 'event': 'state',
229 16 Saúl Ibarra Corretgé
 'session': '20c40185-1ef2-419e-b91a-70415778acb4',
230 16 Saúl Ibarra Corretgé
 'sylkrtc': 'session_event'}
231 16 Saúl Ibarra Corretgé
</pre>
232 16 Saúl Ibarra Corretgé
233 16 Saúl Ibarra Corretgé
<pre>
234 16 Saúl Ibarra Corretgé
{'data': {'reason': '200 to BYE', 'state': 'terminated'},
235 1 Saúl Ibarra Corretgé
 'event': 'state',
236 1 Saúl Ibarra Corretgé
 'session': '20c40185-1ef2-419e-b91a-70415778acb4',
237 16 Saúl Ibarra Corretgé
 'sylkrtc': 'session_event'}
238 16 Saúl Ibarra Corretgé
</pre>
239 16 Saúl Ibarra Corretgé
240 19 Saúl Ibarra Corretgé
Valid session states:
241 17 Saúl Ibarra Corretgé
242 19 Saúl Ibarra Corretgé
* incoming: initial state for incoming sessions, no state event is sent for this state.
243 19 Saúl Ibarra Corretgé
* progress: on outgoing sessions, when in progress.
244 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. 
245 19 Saúl Ibarra Corretgé
* established: the session has been established media-wise.
246 19 Saúl Ibarra Corretgé
* terminated: session was terminated, the "reason" attribute indicates the termination reason.
247 4 Saúl Ibarra Corretgé
248 4 Saúl Ibarra Corretgé
h2. Configuration
249 4 Saúl Ibarra Corretgé
250 2 Saúl Ibarra Corretgé
TODO
251 2 Saúl Ibarra Corretgé
252 23 Saúl Ibarra Corretgé
h2. JavaScript client library
253 1 Saúl Ibarra Corretgé
254 1 Saúl Ibarra Corretgé
In order to interact with SylkServer's WebRTC gateway, we provide the "sylkrtc.js":http://projects.ag-projects.com/projects/sylkrtc JavaScript library. It 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.