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:

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.

Table 6.1 Create WebSocket Name Operation

Operation

Configuration

Create a new type

HTTP Verb

POST

URL

http://<host>[:<port>]/dds/v1/websocket_connections

Content-Type

application/dds-web+json

Example Body
{ "name": <websocket_name> }
Preconditions

There cannot be any websocket name with the same name in the system.

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.

Table 6.2 HELLO Message Fields

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:

Table 6.3 REQUEST Message Elements

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:

Table 6.4 RESPONSE Message Elements

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
                }
            }
        ]
    }
}