A JSONRTC Protocol Reference

This appendix provides reference information for the WebRTC Session Controller JSONRTC Protocol used by WebRTC Session Controller Signaling Engine (Signaling Engine).

About the JSONRTC Protocol

WebRTC Session Controller uses this protocol to communicate with WebRTC-enabled browser client applications. It establishes the sessions and subsessions that you use to pass messages between WebRTC Session Controller and its client applications inside WebSocket connections.

You can also use this protocol to create new WebRTC Session Controller packages for your WebRTC Session Controller implementation.

See "About Building JSON to SIP Communication" for more information about how WebRTC Session Controller handles WebSocket connections, sessions, and subsessions.

While WebRTC Session Controller uses this protocol to communicate with JavaScript-based applications by default, this protocol also communicates with client applications based on different operating systems. Your client application opens the WebSockets necessary for the JSONRTC protocol subsessions to communicate with.

The JSON protocol operates between a WebRTC client and WebRTC server which can be an application server or a gateway. The WebRTC client can be a WebRTC-enabled browser (Chrome and Firefox), Android or iOS native applications.

Initiating a HTTP/HTTPS Handshake with Signaling Engine

The JSONRTC protocol is a sub protocol of the WebSocket protocol. You establish a handshake with a WebSocket protocol to initiate communication between the two. The handshake establishes a connection between the client (usually an application in a browser) and the Signaling Engine server inside HTTP/HTTPS. Once the client receives the handshake response, communication can proceed. The handshake is an HTTP GET /chat message using webrtc.oracle.com as the value for Sec-WebSocket-Protocol. For Example:

GET /chat HTTP/1.1
Host: server.wsc_IP.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://client_IP.com
Sec-WebSocket-Protocol: webrtc.oracle.com
Sec-WebSocket-Version: 13

Where:

wsc_IP is the domain name of the Signaling Engine server.

client_IP is the domain name of the client.

The handshake includes a 101 Switching Protocols entry to allow the connection, as shown in this example handshake reply:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: webrtc.oracle.com

Once the client receives the handshake response, the client and Signaling Engine server can communicate further.

Immediately after establishing a WebSocket connection, the client sends a JSONRTC connect message to establish the WebRTC Session Controller JSONRTC session. Once WebRTC Signaling Controller accepts the connect message, it responds by sending back a session_id. If the WebSocket connection is broken unexpectedly, for example by a network problem, the client can re-establish the session by starting a new websocket connection with the original session_id in a connect message.

Closing a JSONRTC Session

You close a JSONRTC session by invoking the session.close() function.

About JSONRTC Sessions and SubSessions

See "About Sessions and Subsessions" for details on how this protocol establishes and manipulates sessions and subsessions.

JSONRTC uses a session_id field instead of a Message Broker WebSocket Subprotocol (MBWS) connection_name to identify the WebSocket session. The session_id field value must be unique across time and space to work with geographically redundant clusters.

The subsession_id is the session_id value with a c or s prefix added to it.

Also see "Initiating a HTTP/HTTPS Handshake with Signaling Engine" for more information about using session_id to reconnect a session.

About Message Reliability

This protocol uses the MessageBroker WebSocket Subprotocol (MBWS) as basis for message reliability. For more information on MBWS, see the MBWS specification:

http://tools.ietf.org/html/draft-hapner-hybi-messagebroker-subprotocol-03

About the JSONRTC Session Controller Messages

The basic communication unit used between a WebRTC-enabled client application and the WebRTC Session Controller JSONRTC protocol is a message. Signaling Engine communication can be synchronous or asynchronous.

About Messages

Each message executes a part of the whole message flow in a package. The action header defines the specific action each message carries out in a subsession in a specific package. For example, a "START" action will start a "call" or start a "message-notification". A SHUTDOWN action will end a "call" subsession or "messageNotification" subsession. The client and server do not make any assumptions of a particular action outside the defined behavior of the package.

All messages with type=message are asynchronous in nature and do not expect to receive a response message. Such messages are acknowledged. In case of an error, you receive an error message.

If you want to cancel a START message, send the CANCEL message before sending the START final response.

The CONNECT action is not associated with any package. CONNECT represents establishing a logical session. All other actions are specific to subsessions.

About Acknowledgements and Error Messages

An Acknowledgement message indicates that the message (and all the messages lower than the sequence) has reached the other side. An Error Message indicates that the message with the specified sequence met with an error.

Acknowledgement and error messages are applicable for requests, responses and messages. One side receives an acknowledgement with a sequence that is higher than a particular message and has not received an error message yet. This sequence indicates that the message sent has been received successfully by the other side. You can configure your applications to receive acknowledgement messages for every message.

About the Message Components

Each messages includes these components:

This section also includes "Example Message Bodies" that you can use for reference.

Control Headers

The control header specifies information that the client and server use to handle (control) the message. It includes information required for WebSocket reconnect reliability, error, the message type, session ID, message state, and so on. Typically Signaling Engine uses this information itself, not applications or Groovy scripts.

type

The control type of JSON message. Can be one of:

request

A message, such as an offer message, that requires a response. A protocol frame with control type request may also contain a payload header.

response

This message is a response to a request message. For example, an answer or a provisional answer, pranswer in JavaScript Session Establishment Protocol (JSEP). A protocol frame with control type request may also contain a payload header.

message

A message that does not require a response. For example notification, or publish. A protocol frame with control type request may also contain a payload header.

acknowledgement

A message that acknowledges another message. Cannot contain a payload header.

error

Indicates that an error has arrived. Cannot contain a payload header.

package_type

Optional. The package is the type of service or functionality that the message handles and identifies the Signaling Engine package that the message applies to. The register, call, flash, message_notification, capability, messaging, chat, and file_transfer types are defined by default. If no package_type is specified, Signaling Engine assumes that the default call package is used for all messages except messages with a connect action. The connect action messages attempt to establish a session and are not associated with a package. See "Creating Packages" for details about the Signaling Engine packages.

session_id

Identifies a WebSocket session. The server creates the session ID and returns it to the client in the CONNECT response. A CONNECT message containing a session ID reestablishes a JSONRTC session. This value must be completely unique so that it may be used across redundant clusters. A session ID has the same role as the MessageBroker WebSocket Subprotocol (MBWS) connection-name.

sequence

A serial number that uniquely identifies a message in a JSONRTC session. Each side of the WebSocket connection maintains its own serial number counts, starting with 1.

Note the following exceptions for the sequence header:

  • If a message is for WebSocket re-connection, the sequence number will not be set in the message.

  • In an acknowledge message, this header indicates the specific message that came from the peer and does not indicate the serial number of this message.

ack_sequence

Optional. It identifies a particular message within a JSONRTC session. This header acknowledges that a specified server message has been received by the client or, likewise, that a specified client message has been received by the server. For example, if a client receives a message with ack_sequence=2, it means that the server has received the second message sent by the client. All messages with a lower value than specified by ack_sequence are also considered acknowledged.

If the sender has not received any message from its peer, the value of ack_sequence is 0.

Note:

Do not set the ack_sqeuence header for an acknowledgement message. An acknowledgement message uses the sequence header to confirm the peer side.
subsession_id

Identifies a subsession within a session. The sequence numbers are incremented each time a new session is started. The client and server keep separate subsession ID counts. The subsession ID typically includes a c prefix if the subsession originated with the client and an s prefix if it originated with the server. An implementation can also choose to use a globally unique identifier as the subsession ID.

For example, the second client-originated subsession has the value "subsession_id":"c2". The seventh server-originated session uses the value "subsession_id":"s7".

correlation_id

A string that identifies a specific message within a session. It can simply be a sequence number incremented each time a new message is sent. When the control header type is response, acknowledge, or error, the correlation_id associates it with the actual message.

The client and server keep separate message counts. When a client request does not have a correlation_id, server may assign one for response. Messages from the client have a ”c” suffix and messages from the server have an ”s" suffix. For example, the third client-originated message has the value ”correlation_id”:"c3". The sixth server-originated message has the value "correlation_id":"s6".

When a client request does not have a correlation_id, the server assigns one for its response.

message_state

Identifies the message state as subsequent, or final. Only subsequent or final response messages need specify the message_state.

For example: "message_state":"final"

version

Identifies the JSONRTC protocol version that message sender supports (client or server). If none is present in the message version, it is assumed to be "3.0".

General Headers

The general header contains information related to the specific action involved in the message. For example, for a START request, such information would contain who initiated the request, for whom it is intended, and so on.

The general header includes fields that Signaling Engine uses to build up and tear down calls. These fields are specific to one or more packages and are available to use in both client applications and Groovy scripts. Your application can add additional headers to this section. Such headers may be mapped by a gateway server to a SIP header or a parameter.

action

The purpose of the message. Can be one of:

connect

Establishes a session with the server. These general headers are only used with the CONNECT action.

cslr

Optional. Sent with the session_id of a session to reconnect. Uses the sequence number of the last message received from the client to identify the session.

cslw

Optional. Sent with the session_id of a session to reconnect. Uses the lower bound of the messages in the client's retained window to identify the session.

csuw

Optional. Sent with the session_id of a session to reconnect. Uses the upper bound of the messages in the client's retained window to identify the session.

sslr

Optional. Sent with the session_id of a session to reconnect. Uses the sequence number of the last message received by the server to identify the session.

start

Starts a session with a specific package.

complete

Announces that the media session has been established.

hibernate

Announces that the session is going to hibernate. Hibernates a protocol level session with the server.

notify

Equivalent to Notification of Notification Server.

shutdown

Shuts down a session opened by a specific request.

prack

Pre-acknowledges provisional responses.

enquiry

Queries information (about capabilities) from the peer side.

send

Sends out data.

trickle

Sends out ICE candidates. Trickle SDP candidate information from the peer.

initiator

Optional. Identifies the URI of the user initiating the HTTP request. If this value exists, it may be set by the client or the HTTP session. In certain cases, a value may not even exist (such as when a random user clicks on a web page to talk with customer care).

target

Optional. Identifies the URI of the Signaling Engine server that is targeted by the message. Can be obtained from the HTTP session.

error_code

Optional. In error type messages, lists the error message.

reason

Optional. The description of the error.

response_code

Optional. Specifies the result for a response message, especially in the call package. For example, "180", "200", and so on.

enquiry_data

Optional. This is the enquiry data that is the result of an enquiry action. In most cases it is for the capability package.

wsc_id

Optional. Used in a re-connect response message only. It identifies the server id with which WebSocket is connecting.

Package-Specific General Headers

Some headers are specified only for certain packages.

message_notification, expiry (xp)

Optional. Represents the subscription's expiration time for receiving message-summary notifications.

Authentication-Specific General Headers

The authentication headers are specific to client authentication and authorization.

authenticate

Optional. Represents authentication information from the server. If the server leverages DIGEST for authentication, this header contains {scheme, username, realm, qop, opaque, nonce, cnonce, ha1, challenge_code, algorithm}.

authorization

Optional. This header represents the authorization response to the server. If DIGEST is leveraged, this header contains {scheme, username, realm, qop, opaque, nonce, cnonce, ha1, challenge_code, algorithm}. For more details on this header, see https://www.ietf.org/rfc/rfc2617.txt.

The ha1 value is calculated with the following steps:

  1. A1 calculation:

    • If algorithm=MD5 or is unspecified

      A1 = username-value ":" realm-value ":" password
      
    • If algorithm=MD5-sess

      A1 = H(username-value ":" realm-value ":" password) ":" nonce-value ":" cnonce-value
      
  2. ha1=H(A1)

Where username-value, realm-value, nonce-value, and cnonce-value are strings without quote marks. H means the string obtained by applying the checksum algorithm to A1.

Message Payloads

The message payload is specific to the Signaling Engine package for which the message is used.

For:

  • The call, chat, and file_transfer packages, the default payload is an SDP offer or answer.

  • The messaging package, the payload is content that represents the text message.

  • The message-notification or a register with the hibernate action, the payload is JSON data with the exact message alerts.

Providing Client Information as a Payload

The mechanism to register with the Cloud Notification system is entirely up to your (Android or iOS) application and should follow the Android or iOS guidelines or the Customer's own notification registration APIs. For more information on the registration step, see the Android or iOS reference documents, as appropriate.

The WSC Client SDK captures the information required to identify the client and its capability as shown in the following table:

Table A-1 Client Capability Identification Data

Parameter Value Description

family

android/iOS/Chrome/Firefox

Device family

version

41/37/21/8.1

Current version of the Client

appid

com.enterprise.enterpriseId.wsc

Unique application Id. For example,

com.enterprise.xyz.wsc

appversion

3.1

Application version


When the SDK sends it initial registration request, it sends this client identification information to the WSC server as part of that register request.

Here is an example used by a sample Android application:

Example A-1 Payload Data Sent in the Initial Register Request (Android)

{
  "control": {
    "type": "request",
    "package_type": "register",
    "sequence": 1,
    "version": "1.0"
  },
  "header": {
    "action": "connect"
  },
  "payload": {
    "capability": {
      "family": "android",
      "version": 21,
      "appid": "com.enterprise.xyz.wsc"
      "appversion": "3.1"
    },
    "devicetoken": "APA91bFlmPxDGNWp42wCJE8_r09YECG-dEWtzNU1DXACl1IaqFSJdOlxCvO_4K-mkiQO6CS-jVnVxDVXiCQwK5F0dosPMa2bZpiBc6vo";     
  }
}

As shown in Example A-1, the device token identifying the client device is sent. This value stored as part of the Session data in the Cluster state and is used later for sending notifications.

Notification Payloads

The notification sent to the client mobile device contains user parameters and is limited by the cloud notification system.

Add custom data in JSON format. For example:

 "data": {
    "time": "15:16.2342",
    "message": "Incoming Call"
  }

WebRTC Session Controller server converts the message data to suit the cloud messaging system. For the Google cloud messaging system (GCM), this notification contains the registration id for the device as shown here:

Example A-2 Notification Payload (for GCM)

{ 
  "collapse_key": "wsc_notify",
  "time_to_live": 300,
  "delay_while_idle": true,
  "data": {
    "time": "15:16.2342",
    "message": "Incoming Call"
  },
  "registration_ids":["APA91bFlmPxDGNWp42wCJE8_r09YECG-dEWtzNU1DXACl1IaqFSJdOlxCvO_4K-mkiQO6CS"]
}

Note:

The additional custom data is passed along without any changes.

Example Message Bodies

The following sections show message body examples.

Connect Request Message
{
   "control": {
    "type":"request",
    "sequence":"1"
   },
   "header": {
    "action":"connect",
    "initator":"bob@example.com",
   }
}
CONNECT Response Message
{
   "control": {
    "type":"response",
    "sequence":"1",
    "correlation_id":"c1",
    "subsession_id":"c1",
    "session_id":"Hyi89JUThhjjR"
   },
   "header": {
    "action":"connect"
   }
}
CONNECT Request with Device Token
{
   "control":{
    "type":"request",
    "package_type":"register",
    "sequence":1,
    "version":"3.0"
   },
  
 "header":{
    "action":"connect",
    "initiator":"alice@example.com",
    "target":"alice@example.com"
   },
  
  "payload":{
   "capability":{
    "appid":"oracle.wsc.samples.web",
    "appversion":"0.1",
    "family":"Chrome",
    "version":"45.0.2454.101"
   },
   "devicetoken":"APA91bHIx2iEtOjulPrVQxDQPIwwHscTXRpkzTJZJoYr7ajWH0XPglQ10Y8J7pNn3Sh8RnchKNno-BhmfvJqrO_8EFx-AGilpG8YlV9wbI2C9OlOmw5jAstOtpxkuj0IMBHViX4y3uQaRAqFB_YvprHBHqRzBTZ6hvqaDwN1OXiyANk-LYTIVWXKep-Hp03K-5VpFEY3zbBg"
  }
}
START Request Message (with initiator/target)
{
   "control": {
    "package_type": "call",
    "type":"request",
    "sequence":"2",
   },
   "header": {
    "action":"start",
    "initator":"bob@example.com",
    "target":"alice@example.com",
   },
   "payload": {
     "<offer_sdp>"
   }
}
START Response Message (with initiator/target)
{
   "control": {
    "package_type": "call",
    "type":"response",
    "message_state":"final",
    "sequence":"2",
    "correlation_id":"c2"
    "subsession_id":"c2"
   },
   "header": {
    "action":"start"
    "initator":"bob@att.com",
    "target":"alice@att.com",
   },
   "payload": {
     "<answer_sdp>"
   }
}
START Request Message (without initiator/target)
{
"control": {
    "package_type": "call",
    "type":"request",
    "sequence":"2"
   },
   "header": {
    "action":"start"
   },
   "payload": {
     "<offer_sdp>"
   }
}
START Request Message (without initiator/target)
{
   "control": {
    "package_type": "call",
    "type":"response"
    "message_state":"final"
    "sequence":"2",
    "correlation_id":"c2"
    "subsession_id":"c2"
   },
   "header": {
    "action":"start"
   },
   "payload": {
     "<pranswer_sdp>"
   }
}
START Offer with Changed Media
{
"control": {
    "package_type": "call",
    "type":"request",
    "sequence":"3",
    "subsession_id":"c2"
   },
   "header": {
    "action":"start"
   },
   "payload": {}
     "<offer_sdp>"
   }
}
HIBERNATE Request Message
{
"control": {
        "type": "request",
        "package_type": "register",
        "session_id": "pQAAAVBltniS54z1CuCiXp9AffIAAAAD_23",
        "subsession_id": "50d890f2-d357-4847-9278-442d5964fc32",
        "correlation_id": "c2",
        "version": "1.0"
    },
    "header": {
        "action": "hibernate",
        "ttl": 3600
    },
    "payload": {}
}
HIBERNATE Response Message
{
"header": {
        "response_code": 200,
        "action": "hibernate"
    },
    "control": {
        "sequence": 2,
        "subsession_id": "50d890f2-d357-4847-9278-442d5964fc32",
        "message_state": "final",
        "session_id": "pQAAAVBltniS54z1CuCiXp9AffIAAAAD_23",
        "correlation_id": "c2",
        "type": "response",
        "package_type": "register",
        "version": "1.0"
    }
}

Note that:

  • The response_code indicates if the other side accepted or rejected the request.

  • The ttl parameter in the Hibernate response contains the value the WSC server finally chose for the Session-Alive interval. The WSC server maintains a maximum interval depending on the policy set for each type of client device.

    If the requested value was more than the accepted maximum for the server, the value will revert to the server's maximum value. If the value is too lower than the default value for the server, the server reverts to its default value.

SHUTDOWN Message
{
   "control": {
    "package_type": "call",
    "type":"message"
    "sequence":"4",
    "subsession_id":"c2"
   },
   "header": {
    "action":"shutdown"
   }
}
ACKNOWLEGEMENT Message
{
"control": {
    "type":"acknowledgement"
    "sequence":"5"
   }
}
ERROR Message
{
   "control": {
    "package_type": "call"
    "type":"error"
    "sequence":"6",
    "correlation_id":"c2"
    "subsession_id":"c2"
    "error_code":"480"
   }
}
ENQUIRY Request Message
{
    "package_type": "capability"
    "type":"request",
    "sequence":"1",
    "correlation_id":"c1"
    "subsession_id":"c1"
  }
  "header": {
   "action":"enquiry",
   "enquiry_data":"IM/CHAT,VS",
   "initiator":"bob@att.com",
   "target":"alice@att.com",
  }
}
Enquiry Response Message
{
   "control": {
    "package_type": "capability",
    "type":"response",
    "message_state":"final",
    "sequence":"1",
    "correlation_id":"c1"
    "subsession_id":"c1"
   }
   "header": {
    "action":"enquiry",
    "enquiry_data""IM/CHAT, FT",
    "initator":"bob@att.com",
    "target":"alice@att.com",
   }
}
SEND Message
{
   "control": {
    "package_type": "messaging"
    "type":"message"
    "sequence":"1",
    "correlation_id":"c1"
    "subsession_id":"c1"
   }
   "header": {
    "action":"send"
    "initiator":"bob@att.com",
    "target":"alice@att.com",
   }
   "payload": {
    "content": <message content>
   }
}
TRICKLE Message
{
    "control": {
        "type": "message",
        "package_type": "call",
        "session_id": "pQAAAVBlDjliO2V9HrgoM9QDd4EAAAAF_255",
        "subsession_id": "9356a8a5-8b48-4b8d-9355-0c43315114d3",
        "sequence": 4,
        "ack_sequence": 3,
        "version": "3.0"
    },
    "header": {
        "action": "trickle",
        "initiator": "alice@example.com",
        "target": "bob@example.com"
    },
    "payload": {
        "candidates": "a=mid:audio\r\na=candidate:134500521 1 ..."
    }
}