WebRTC
Version 24 (Adrian Georgescu, 08/01/2015 06:03 am) → Version 25/33 (Adrian Georgescu, 08/01/2015 06:14 am)
h1. SylkServer WebRTC gateway application
Starting with version 3.0.0 SylkServer features includes a WebRTC gateway capacities. This application. The application implements a WebSocket protocol which WebRTC endpoints can use in order to interact bidirectionally with the SIP world.
h2. Deployment scenarios
* Web page calling using a WebRTC enabled web browsers like Firefox and Google Chrome by using a standard SIP account
* Mobile iOS and Android application for audio and video calling
h2. Architecture
The SylkServer WebRTC gateway application consists of several 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.
TODO: diagram
All interaction with the gateway from the Web's side is performed through a WebSocket connection using the "sylkRTC protocol" described in this document.
h5. Registration
This function is equivalent to SIP REGISTER method and allows an end-point to receive incoming calls.
h5. Audio / video sessions
This function is equivalent to SIP INVITE method and allows an end-point to establish audio and video sessions using RTP protocol.
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.
h5. Chat sessions
This function is equivalent to SIP INVITE method and allows Not implemented yet, consider this an end-point to establish chat sessions using MSRP protocol. early blueprint.
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.
h5. Contacts management and presence
This function corresponds to its equivalent XCAP protocol GET/PUT/DELETE methods. Not implemented yet, consider this an early blueprint.
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.
h5. Presence
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.
h2. WebSocket API
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.
The API uses JSON messages and is modeled around 2 concepts: requests and events. We call this the sylkRTC protocol.
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.
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.
All messages are valid JSON and contain the "sylkrtc" key indicating the message type. A message without the "sylkrtc" key is an invalid message.
h3. Establishing the connection
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:
<pre>
var conn = new WebSocket('wss://example.com/webrtcgateway/ws', 'sylkRTC-1');
</pre>
After the connection is established, a 'ready' event will be sent to the client, indicating that the connection is ready to be used:
<pre>
{"event": "ready", "sylkrtc": "event"}
</pre>
Example:
<pre>
var conn = new WebSocket('wss://example.com/webrtcgateway/ws', 'sylkRTC-1');
conn.onmessage = function(event) {
var message = JSON.parse(event.data);
switch (message.sylkrtc) {
case 'event':
if (message.event === 'ready') {
console.log('Ready to rock!');
}
break;
default:
console.log('Received message type: ' + message.sylkrtc);
break;
}
};
</pre>
h3. Account management
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
Note: it's not necessary to register an account in order to make outgoing calls.
h5. account-add
Configures an account on the current connection.
<pre>
{'account': 'saghul@sip2sip.info',
'password': '884edfee38ed471b8a15006700139485',
'sylkrtc': 'account-add',
'transaction': '04013f0f-25bb-4082-a02f-44399df492ff'}
</pre>
The password MUST be in "HA1 format":https://en.wikipedia.org/wiki/Digest_access_authentication#Overview
h5. account-remove
Removes an account from the current connection.
<pre>
{'account': 'saghul@sip2sip.info',
'sylkrtc': 'account-remove',
'transaction': 'bd3ee25d-5f16-4f76-b34e-8ac3fe0a4ac0'}
</pre>
h5. register
Triggers the account registration via SIP REGISTER method. SIP.
<pre>
{'account': 'saghul@sip2sip.info',
'sylkrtc': 'account-register',
'transaction': 'bcb87b0f-0cc7-42a9-897e-81f035910670'}
</pre>
The registration progress will be reported in form of events.
<pre>
{'account': 'saghul@sip2sip.info',
'data': {'state': 'registering'},
'event': 'registration_state',
'sylkrtc': 'account_event'}
{'account': 'saghul@sip2sip.info',
'data': {'state': 'registered'},
'event': 'registration_state',
'sylkrtc': 'account_event'}
</pre>
Example of failed registration:
<pre>
{'account': 'saghul@sip2sip.info',
'data': {'reason': '904 Operation has no matching challenge ',
'state': 'failed'},
'event': 'registration_state',
'sylkrtc': 'account_event'}
</pre>
h5. account-unregister
Unregister the account, via SIP.
<pre>
{'account': 'saghul@sip2sip.info',
'sylkrtc': 'account-unregister',
'transaction': '1c81eea0-b247-4ced-b3b3-3ced1eba810e'}
</pre>
h3. Sessions
h5. Incoming sessions
Incoming sessions are received via an *incoming_session* event:
<pre>
{'account': 'saghul@sip2sip.info',
'data': {'originator': '31208005163@ag-projects.com', 'sdp': '...'},
'event': 'incoming_session',
'session': '509b256aa6a14540a2a37553e6bd33e1',
'sylkrtc': 'account_event'}
</pre>
The "session-answer" request can be used in order to answer an incoming session:
<pre>
{'sdp': '...',
'session': '38dffdf81acb44b2b11b61f4488c4ca9',
'sylkrtc': 'session-answer',
'transaction': '179a855f-75a0-45a4-b5ef-0be8eb8389d1'}
</pre>
h5. Outgoing sessions
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.
<pre>
{'account': 'saghul@sip2sip.info',
'sdp': '...',
'session': '20c40185-1ef2-419e-b91a-70415778acb4',
'sylkrtc': 'session-create',
'transaction': '7afcb91a-8a64-4664-9448-8cb760492e1f',
'uri': '3333@sip2sip.info'}
</pre>
h5. Trickle ICE
As new candidates are discovered they must be sent to the server using 'session-trickle' requests:
<pre>
{'candidates': [{'candidate': 'candidate:0 1 UDP 2130379007 192.168.99.44 59051 typ host',
'sdpMLineIndex': 0,
'sdpMid': ''}],
'session': '20c40185-1ef2-419e-b91a-70415778acb4',
'sylkrtc': 'session-trickle',
'transaction': 'ecf777d8-7d26-4f16-bace-18f6fae5d8f8'}
</pre>
Use an empty list of candidates to indicate that no more candidates will be sent.
This applies to both incoming and outgoing calls.
There is no need to wait for the acknowledgement for the "session-create" or "session-answer" request before sending "session-trickle" requests.
h5. Terminating sessions
A session can be terminated at any time by sending the "session-terminate" request:
<pre>
{'session': '38dffdf81acb44b2b11b61f4488c4ca9',
'sylkrtc': 'session-terminate',
'transaction': '4d169de8-fe55-41f8-9a5c-c5f66c0a23c7'}
</pre>
h5. Events
Session state related events are reported via the "session_event" event:
<pre>
'data': {'state': 'established'},
'event': 'state',
'session': '38dffdf81acb44b2b11b61f4488c4ca9',
'sylkrtc': 'session_event'}
</pre>
<pre>
{'data': {'sdp': '...', 'state': 'accepted'},
'event': 'state',
'session': '20c40185-1ef2-419e-b91a-70415778acb4',
'sylkrtc': 'session_event'}
</pre>
<pre>
{'data': {'reason': '200 to BYE', 'state': 'terminated'},
'event': 'state',
'session': '20c40185-1ef2-419e-b91a-70415778acb4',
'sylkrtc': 'session_event'}
</pre>
Valid session states:
* incoming: initial state for incoming sessions, no state event is sent for this state.
* progress: on outgoing sessions, when in progress.
* 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.
* established: the session has been established media-wise.
* terminated: session was terminated, the "reason" attribute indicates the termination reason.
h2. Zero-configuration Configuration
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 signed by an authority recognised by the web application. TODO
h2. JavaScript client library
In order to interact with SylkServer's WebRTC gateway, we provide the "sylkrtc.js":http://projects.ag-projects.com/projects/sylkrtc JavaScript library is provided. This library 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.
Starting with version 3.0.0 SylkServer features includes a WebRTC gateway capacities. This application. The application implements a WebSocket protocol which WebRTC endpoints can use in order to interact bidirectionally with the SIP world.
h2. Deployment scenarios
* Web page calling using a WebRTC enabled web browsers like Firefox and Google Chrome by using a standard SIP account
* Mobile iOS and Android application for audio and video calling
h2. Architecture
The SylkServer WebRTC gateway application consists of several 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.
TODO: diagram
All interaction with the gateway from the Web's side is performed through a WebSocket connection using the "sylkRTC protocol" described in this document.
h5. Registration
This function is equivalent to SIP REGISTER method and allows an end-point to receive incoming calls.
h5. Audio / video sessions
This function is equivalent to SIP INVITE method and allows an end-point to establish audio and video sessions using RTP protocol.
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.
h5. Chat sessions
This function is equivalent to SIP INVITE method and allows Not implemented yet, consider this an end-point to establish chat sessions using MSRP protocol. early blueprint.
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.
h5. Contacts management and presence
This function corresponds to its equivalent XCAP protocol GET/PUT/DELETE methods. Not implemented yet, consider this an early blueprint.
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.
h5. Presence
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.
h2. WebSocket API
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.
The API uses JSON messages and is modeled around 2 concepts: requests and events. We call this the sylkRTC protocol.
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.
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.
All messages are valid JSON and contain the "sylkrtc" key indicating the message type. A message without the "sylkrtc" key is an invalid message.
h3. Establishing the connection
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:
<pre>
var conn = new WebSocket('wss://example.com/webrtcgateway/ws', 'sylkRTC-1');
</pre>
After the connection is established, a 'ready' event will be sent to the client, indicating that the connection is ready to be used:
<pre>
{"event": "ready", "sylkrtc": "event"}
</pre>
Example:
<pre>
var conn = new WebSocket('wss://example.com/webrtcgateway/ws', 'sylkRTC-1');
conn.onmessage = function(event) {
var message = JSON.parse(event.data);
switch (message.sylkrtc) {
case 'event':
if (message.event === 'ready') {
console.log('Ready to rock!');
}
break;
default:
console.log('Received message type: ' + message.sylkrtc);
break;
}
};
</pre>
h3. Account management
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
Note: it's not necessary to register an account in order to make outgoing calls.
h5. account-add
Configures an account on the current connection.
<pre>
{'account': 'saghul@sip2sip.info',
'password': '884edfee38ed471b8a15006700139485',
'sylkrtc': 'account-add',
'transaction': '04013f0f-25bb-4082-a02f-44399df492ff'}
</pre>
The password MUST be in "HA1 format":https://en.wikipedia.org/wiki/Digest_access_authentication#Overview
h5. account-remove
Removes an account from the current connection.
<pre>
{'account': 'saghul@sip2sip.info',
'sylkrtc': 'account-remove',
'transaction': 'bd3ee25d-5f16-4f76-b34e-8ac3fe0a4ac0'}
</pre>
h5. register
Triggers the account registration via SIP REGISTER method. SIP.
<pre>
{'account': 'saghul@sip2sip.info',
'sylkrtc': 'account-register',
'transaction': 'bcb87b0f-0cc7-42a9-897e-81f035910670'}
</pre>
The registration progress will be reported in form of events.
<pre>
{'account': 'saghul@sip2sip.info',
'data': {'state': 'registering'},
'event': 'registration_state',
'sylkrtc': 'account_event'}
{'account': 'saghul@sip2sip.info',
'data': {'state': 'registered'},
'event': 'registration_state',
'sylkrtc': 'account_event'}
</pre>
Example of failed registration:
<pre>
{'account': 'saghul@sip2sip.info',
'data': {'reason': '904 Operation has no matching challenge ',
'state': 'failed'},
'event': 'registration_state',
'sylkrtc': 'account_event'}
</pre>
h5. account-unregister
Unregister the account, via SIP.
<pre>
{'account': 'saghul@sip2sip.info',
'sylkrtc': 'account-unregister',
'transaction': '1c81eea0-b247-4ced-b3b3-3ced1eba810e'}
</pre>
h3. Sessions
h5. Incoming sessions
Incoming sessions are received via an *incoming_session* event:
<pre>
{'account': 'saghul@sip2sip.info',
'data': {'originator': '31208005163@ag-projects.com', 'sdp': '...'},
'event': 'incoming_session',
'session': '509b256aa6a14540a2a37553e6bd33e1',
'sylkrtc': 'account_event'}
</pre>
The "session-answer" request can be used in order to answer an incoming session:
<pre>
{'sdp': '...',
'session': '38dffdf81acb44b2b11b61f4488c4ca9',
'sylkrtc': 'session-answer',
'transaction': '179a855f-75a0-45a4-b5ef-0be8eb8389d1'}
</pre>
h5. Outgoing sessions
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.
<pre>
{'account': 'saghul@sip2sip.info',
'sdp': '...',
'session': '20c40185-1ef2-419e-b91a-70415778acb4',
'sylkrtc': 'session-create',
'transaction': '7afcb91a-8a64-4664-9448-8cb760492e1f',
'uri': '3333@sip2sip.info'}
</pre>
h5. Trickle ICE
As new candidates are discovered they must be sent to the server using 'session-trickle' requests:
<pre>
{'candidates': [{'candidate': 'candidate:0 1 UDP 2130379007 192.168.99.44 59051 typ host',
'sdpMLineIndex': 0,
'sdpMid': ''}],
'session': '20c40185-1ef2-419e-b91a-70415778acb4',
'sylkrtc': 'session-trickle',
'transaction': 'ecf777d8-7d26-4f16-bace-18f6fae5d8f8'}
</pre>
Use an empty list of candidates to indicate that no more candidates will be sent.
This applies to both incoming and outgoing calls.
There is no need to wait for the acknowledgement for the "session-create" or "session-answer" request before sending "session-trickle" requests.
h5. Terminating sessions
A session can be terminated at any time by sending the "session-terminate" request:
<pre>
{'session': '38dffdf81acb44b2b11b61f4488c4ca9',
'sylkrtc': 'session-terminate',
'transaction': '4d169de8-fe55-41f8-9a5c-c5f66c0a23c7'}
</pre>
h5. Events
Session state related events are reported via the "session_event" event:
<pre>
'data': {'state': 'established'},
'event': 'state',
'session': '38dffdf81acb44b2b11b61f4488c4ca9',
'sylkrtc': 'session_event'}
</pre>
<pre>
{'data': {'sdp': '...', 'state': 'accepted'},
'event': 'state',
'session': '20c40185-1ef2-419e-b91a-70415778acb4',
'sylkrtc': 'session_event'}
</pre>
<pre>
{'data': {'reason': '200 to BYE', 'state': 'terminated'},
'event': 'state',
'session': '20c40185-1ef2-419e-b91a-70415778acb4',
'sylkrtc': 'session_event'}
</pre>
Valid session states:
* incoming: initial state for incoming sessions, no state event is sent for this state.
* progress: on outgoing sessions, when in progress.
* 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.
* established: the session has been established media-wise.
* terminated: session was terminated, the "reason" attribute indicates the termination reason.
h2. Zero-configuration Configuration
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 signed by an authority recognised by the web application. TODO
h2. JavaScript client library
In order to interact with SylkServer's WebRTC gateway, we provide the "sylkrtc.js":http://projects.ag-projects.com/projects/sylkrtc JavaScript library is provided. This library 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.