6. WebSocket API
This section focuses on Web Integration Service’s WebSocket API, which enables client applications to participate as first-class citizens in the DDS Global Data Space.
In particular, this section describes:
An API overview (Section 6.1).
Connection establishment using WebSocket (Section 6.2).
How to write and read data using WebSocket (Section 6.3).
6.1. API Overview
6.1.1. WebSocket Environment
The Web-Enabled DDS OMG standard dictates that a non-secure WebSocket connection shall be identified by the URL schema:
ws://<servername>[:<port>]/dds/v1/<connectionName>
and Secure WebSocket connections shall be identified by the URL schema:
wss://<servername>[:<port>]/dds/v1/<connectionName>
Also, the standard says that <connectionName>
should be chosen by the
client and allows the client to establish multiple WebSocket connections and
associate different resources with each.
In order to be compliant with the standard, Web Integration Service adds a REST endpoint that allows clients to create these connection names. Once the connection names have been created, clients can establish connections and start sending WebSocket messages to interact with the DDS environment.
6.1.2. Message Kinds
Web Integration Service’s WebSocket API defines a set of message kinds, which allow you to send and receive samples of DDS data using both XML and JSON format to represent data samples.
Web Clients can exchange the following types of messages with the service instances: HELLO, HELLO_OK, HELLO_FAIL, REQUEST, RESPONSE, BIND, B_REQUEST, and B_PUSH. Here is a short overview of the types of messages.
Since the WebSocket API offers an improvement only in read and write operations, for all other operations that interact with DDS entities, such as create, delete, list, update and enable operations, you should continue using the REST API (Section 5.1).
As WebSockets support is a new feature, and is not required to use Web Integration Service,
it is disabled by default. Therefore, it will be necessary to add the -enableWebSockets
argument when running Web Integration Service to enable WebSockets support.
6.1.2.1. HELLO Messages
The HELLO message must be the first message sent by the client on each WS/WSS connection. Web Integration Service shall not send any messages or process any messages over a WS/WSS connection until the HELLO message has been received by the connection. The HELLO message format is a colon-separated string of name-values pairs, each terminated by a carriage return (CR) and line feed (LF) character sequence. The following four fields shall appear in the HELLO message:
Accept
Content-Type
OMG-DDS-API-Key
Version
Once the HELLO message has been processed, Web Integration Service will respond with a HELLO_OK or HELLO_FAIL message, depending on whether the handshake was successful or unsuccessful.
6.1.2.2. REQUEST/RESPONSE Messages
Once the WebSocket connection has been established, the client can communicate with Web Integration Service by sending REQUEST messages and receiving RESPONSE messages. The content for REQUEST and RESPONSE messages is equivalent to HTTP requests and responses, albeit with slightly different encoding. Here you can use two types of REQUEST messages:
- GET: As in the REST API, this message is used to read samples of a given DDS DataReader and Web Integration Service will send a RESPONSE message with the read samples.
- POST: As in the REST API, this message is used to write samples to a given DDS DataWriter, then Web Integration Service will send a RESPONSE message to ACK the request.
6.1.2.3. BIND Messages
Writing and reading data is one of the most critical operations performed by a Web Integration Service client. That’s why BIND messages provide a slight improvement over REST or using WebSocket’s REQUEST messages.
- BIND: This message is used to associate a
bind_id
with a DDS endpoint (DataReader/DataWriter) in a WebSocket connection. Each connection can bind to several DDS endpoints. - B_PUSH: Once a DDS DataReader is bound to a WebSocket connection, Web Integration Service will send the samples received by the bound DataReader to the client asynchronously.
- B_REQUEST: The bind request message is used to send samples to a DDS DataWriter previously linked to a
bind_id
.
6.2. Connection Establishment Messages
Section 6.1 provided a high-level overview of the different operations that Web Integration Service’s WebSocket API provides. This section provides a more detailed explanation of the operations that should be performed to establish a connection using the WebSocket API.
6.2.1. Create WebSocket Name
As explained in the Section 6.1, Web Integration Service enables a REST URL to create WebSocket names. The Table (Table 6.1) shows how to create WebSocket names.
Operation |
Configuration |
---|---|
Create a new type |
|
Once the WebSocket name is created, the client can establish a connection to the created WebSocket URL:
ws://<servername>[:<port>]/dds/websocket/<websocket_name>
6.2.2. HELLO Messages
6.2.2.1. HELLO Message
The above table (Table 6.2) contains the four fields and possible content for those fields. As we mention in Section 6.1 The HELLO message format is a colon-separated string of name-values pairs, each terminated by a carriage return (CR) and line feed (LF) character sequence.
Field |
Description |
Values |
---|---|---|
Accept |
Request a particular content type. |
application/dds-web+xml
application/dds-web+json
|
Content-Type |
Provides the used content type. |
application/dds-web+xml
application/dds-web+json
|
OMG-DDS-API-Key |
Key that authorizes the client to establish a connection with Web Integration Service. |
Character string.
(Empty unless the Access Control is enabled. To learn More about Access Control see The Access Control List File.)
|
Version |
Indicates the WebSocket API version. |
1 |
HELLO example:
Content-Type:application/dds-web+json
Accept:application/dds-web+json
OMG-DDS-API-Key:<your-api-key>
Version:1
6.2.2.2. HELLO_FAIL Message
Web Integration Service shall send a HELLO_FAIL Message and close the connection under the following conditions:
If any of the specified fields are missing.
If the OMG-DDS-API-Key is invalid.
If the specified content-type is not recognized or not supported.
If the specified Version is not supported by Web Integration Service.
HELLO_FAIL example:
HELLO_FAIL: <error message>
6.2.2.3. HELLO_OK Message
Web Integration Service shall send HELLO_OK if all the above checks succeed.
HELLO_OK example:
HELLO_OK: Handshake succeeded
6.3. Writing and Reading Data
Section 6.1 provided a high level overview of all the different operations that Web Integration Service’s WebSocket API provides and Section 6.2 explains in depth how to establish connection to the Web Integration Service through WebSocket. Finally this section provides a more detailed explanation of the operations available in the WebSocket API for writing and reading data.
6.3.1. RESQUEST/RESPONSE Messages
These messages are similar to the REST messages defined in Section 5.3. Here are two types of requests, one to write data and another to read data. Each of these requests will receive a corresponding response.
The REQUEST messages contains up to four children: id
, uri
, method
and body
defined in the table below:
Element |
Description |
---|---|
id |
A string set by the client that can be used to associate a response with its corresponding request. |
uri |
Maps to the REST resource name. |
method |
Corresponds to the HTTP method. |
body |
Contains the request body. |
On the other hand the RESPONSE messages contains three children: id
,
return_code
and body
defined in the table below:
Element |
Description |
---|---|
id |
A string set by the client in the request to associate a response with its corresponding request. |
return_code |
Returns OK or an error message depending on whether the operation was successful or unsuccessful |
body |
Contains the response body. |
6.3.1.1. Write Data
The REQUEST message to write data supports XML and JSON, below you can see an example for each content type with the corresponding Web Integration Service’s RESPONSE using the same content type.
XML RESQUEST Example
<request>
<id>RTI-Req-123458</id>
<uri>/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers/MySquareWriter</uri>
<method>POST</method>
<body>
<write_sample_seq>
<sample>
<write_sample_info>
<source_timestamp>
<sec>10</sec>
<nanosec>20</nanosec>
</source_timestamp>
</write_sample_info>
<data>
<color>PURPLE</color>
<x>100</x>
<y>50</y>
<shapesize>30</shapesize>
</data>
</sample>
</write_sample_seq>
</body>
</request>
XML RESPONSE Example
<response>
<id>RTI-Req-123458</id>
<return_code>OK</return_code>
</response>
JSON RESQUEST Example
{
"kind": "request",
"id": "RTI-Req-123459",
"method": "POST",
"uri": "/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers/MySquareWriter",
"body": {
"write_sample_seq":[
{
"write_sample_info": {
"source_timestamp": {
"sec": 15,
"nanosec": 25
}
},
"data": {
"x": 80,
"y": 80,
"color": "ORANGE",
"shapesize": 30
}
}
]
}
}
JSON RESPONSE Example
{
"kind": "response",
"id": "RTI-Req-123459",
"return_code": "OK"
}
6.3.1.2. READ Request
The REQUEST message to read data supports XML and JSON, below you can see an example for each content type with the corresponding Web Integration Service’s RESPONSE using the same content type.
XML RESQUEST Example
<request>
<id>RTI-Req-1234567</id>
<method>GET</method>
<uri>/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers/MySquareReader</uri>
"</request>"
XML RESPONSE Example
<response>
<id>RTI-Req-1234567</id>
<return_code>OK</return_code>
<body>
<read_sample_seq>
<sample>
<read_sample_info>
<source_timestamp>
<sec>10</sec>
<nanosec>20</nanosec>
</source_timestamp>
<valid_data>true</valid_data>
<instance_handle>30219B4293BA6B3FEE6A4FE029813882</instance_handle>
<instance_state>ALIVE</instance_state>
<sample_state>NOT_READ</sample_state>
<view_state>NOT_NEW</view_state>
</read_sample_info>
<data>
<color>purple</color>
<x>100</x>
<y>100</y>
<shapesize>20</shapesize>
</data>
</sample>
</read_sample_seq>
</body>
</response>
JSON RESQUEST Example
{
"kind": "request",
"id": "RTI-Req-1234566",
"method": "GET",
"uri": "/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers/MySquareReader"
}
JSON RESPONSE Example
{
"kind": "response",
"id":"RTI-Req-1234566",
"return_code":"OK",
"body":{
"read_sample_seq":[
{
"read_sample_info":{
"source_timestamp":{
"sec":15,
"nanosec":25
},
"valid_data":true,
"instance_handle":"F7633DE59C2AB88464BA6718232D3921",
"instance_state":"ALIVE",
"sample_state":"NOT_READ",
"view_state":"NOT_NEW"
},
"data":{
"color":"ORANGE",
"x":80,
"y":80,
"shapesize":30
}
}
]
}
}
6.3.2. Read/Write streaming optimization
Improving performance is one of the key motivations for using the Web Integration Service’s WebSockets API. Taking that into acount writing and reading operation are the most critical operation performed by a Web Integration Service’s client.
For the following three messages, Web Integration Service will only send a response if there is an error. Otherwise you can assume the operation was performed successfully. These messages support XML and JSON content.
6.3.2.1. BIND Message
A BIND message is used to link a DDS resource to a bind_id and a WebSocket connection. These DDS resources can be a DDS DataReader or a DDS DataWriter. Even in a single WebSocket connection, a client can bind to multiple DDS entities. The following example shows how to bind a DataReader and a DataWriter in the same WebSocket connection.
XML BIND Example
<bind>
<bind_datawriter>
<bind_id>square_writer</bind_id>
<uri>/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers/MySquareWriter</uri>
</bind_datawriter>
<bind_datareader>
<bind_id>square_reader</bind_id>
<uri>/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers/MySquareReader</uri>
</bind_datareader>
</bind>
JSON BIND Example
{
"kind": "bind",
"body": [
{
"bind_kind":"bind_datawriter",
"bind_id": "square_writer",
"uri": "/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers/MySquareWriter"
},
{
"bind_kind":"bind_datareader",
"bind_id": "square_reader",
"uri": "/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers/MySquareReader"
}
]
}
6.3.2.2. B_PUSH Message
When a client binds a DataReader to a WebSocket connection, Web Integration Service will create an Asynchronous WaitSet to send a B_PUSH message to the client for every sample read by the bound DataReader. Below is an example of a B_PUSH Message.
XML B_PUSH Example
<b_push>
<bind_id>square_reader</bind_id>
<body>
<read_sample_seq>
<sample>
<read_sample_info>
<source_timestamp>
<sec>10</sec>
<nanosec>20</nanosec>
</source_timestamp>
<valid_data>true</valid_data>
<instance_handle>30219B4293BA6B3FEE6A4FE029813882</instance_handle>
<instance_state>ALIVE</instance_state>
<sample_state>NOT_READ</sample_state>
<view_state>NOT_NEW</view_state>
</read_sample_info>
<data>
<color>GREEN</color>
<x>0</x>
<y>0</y>
<shapesize>30</shapesize>
</data>
</sample>
</read_sample_seq>
</body>
</b_push>
JSON B_PUSH Example
{
"kind":"b_push",
"bind_id":"square_reader",
"body":{
"read_sample_seq":[
{
"read_sample_info":{
"source_timestamp":{
"sec":10,
"nanosec":20
},
"valid_data":true,
"instance_handle":"30219B4293BA6B3FEE6A4FE029813882",
"instance_state":"ALIVE",
"sample_state":"NOT_READ",
"view_state":"NEW"
},
"data":{
"color":"GREEN",
"x":0,
"y":0,
"shapesize":30
}
}
]
}
}
6.3.2.3. B_REQUEST Message
When a client binds a DataWriter to a WebSocket connection, the Web Integration Service
will be able to receive B_REQUEST messages associated with the bind_id
that
was linked to the DataWriter. Below is an example of a B_REQUEST Message.
XML B_REQUEST Example
<b_req>
<bind_id>square_writer</bind_id>
<body>
<write_sample_seq>
<sample>
<write_sample_info>
<source_timestamp>
<sec>10</sec>
<nanosec>20</nanosec>
</source_timestamp>
</write_sample_info>
<data>
<color>GREEN</color>
<x>110</x>
<y>70</y>
<shapesize>20</shapesize>
</data>
</sample>
</write_sample_seq>
</body>
</b_req>
JSON B_REQUEST Example
{
"kind": "b_req",
"bind_id": "square_writer",
"body": {
"write_sample_seq":[
{
"write_sample_info": {
"source_timestamp": {
"sec": 15,
"nanosec": 25
}
},
"data": {
"x": 80,
"y": 80,
"color": "PURPLE",
"shapesize": 30
}
}
]
}
}