6. Tutorials

6.1. Hello World Example

The purpose of this example is to get you started with Web Integration Service. We will start from an empty configuration, then add applications and entities using Web Integration Service’s REST API.

To run Web Integration Service from your command shell, go to the installation directory and enter:

$NDDSHOME/bin/rtiwebintegrationservice -cfgName default

This will start an instance of Web Integration Service with an empty configuration. By default, Web Integration Service will listen for HTTP requests on port 8080. To set a different listening port, use the -listeningPorts <portsToListen> argument. For instance:

$NDDSHOME/bin/rtiwebintegrationservice -cfgName default \
    -listeningPorts 8081

To enable HTTPS, append an "s" to the ports specified with -listeningPorts. Use -sslCertificate to specify the path to the certificate to be used by the web server when using HTTPS. The certificate file must combine both the certificate and the private key in the same file. Here is an example:

$NDDHSOME/bin/rtiwebintegrationservice -cfgName default \
    -listeningPorts 8081s -sslCertificate ~/.certificates/some_cert.pem

For a complete list of command-line arguments, see Section 3.3 or run rtiwebintegrationservice -help.

Now that we have a Web Integration Service instance running, we are going to configure a scenario via REST API calls. In particular, we want to create an application that will include entities to publish and subscribe to HelloWorldTopic topics.

6.1.1. Defining Types

Before creating any DDS entity, we first need to define the data types our application will be sending and receiving. The data type associated with HelloWorldTopic consists of two strings and a numeric counter:

  • The first string contains the name of the message’s sender. This field is a “key” because it indicates the identity of the data object.
  • The second string contains the message itself.
  • The third field is a simple counter that the application increments with each sent message.

Web Integration Service uses the Dynamic Data API, so the data type must be defined in the XML configuration for its later dynamic instantiation. This is accomplished by adding the type definition within the <types> tag:

Listing 6.1 Defining Types
<types>
    <const name="MAX_NAME_LEN" type="long" value="64"/>
    <const name="MAX_MSG_LEN" type="long" value="128"/>
    <struct name="HelloWorld">
        <member name="sender" type="string" key="true" stringMaxLength="MAX_NAME_LEN"/>
        <member name="message" type="string" stringMaxLength="MAX_MSG_LEN"/>
        <member name="count" type="long"/>
    </struct>
</types>

To load the types we have defined, we need to call the POST method on /types and pass the XML type representation in the body of the HTTP request. In this example, as well as in the rest of examples, we provide both a raw HTTP Request and the curl command that needs to be run to execute the request.

Listing 6.2 Defining Types—HTTP Request
POST /dds/rest1/types HTTP/1.1
Host: <host>[:<port>]
Content-Length: 381
Content-Type: application/dds-web+xml
Cache-Control: no-cache

<types>
    <const name="MAX_NAME_LEN" type="long" value="64"/>
    <const name="MAX_MSG_LEN" type="long" value="128"/>
    <struct name="HelloWorld">
        <member name="sender" type="string" key="true" stringMaxLength="MAX_NAME_LEN"/>
        <member name="message" type="string" stringMaxLength="MAX_MSG_LEN"/>
        <member name="count" type="long"/>
    </struct>
</types>
Listing 6.3 Defining Types—Curl Example
curl -X POST -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache"  -d '<types>
    <const name="MAX_NAME_LEN" type="long" value="64"/>
    <const name="MAX_MSG_LEN" type="long" value="128"/>
    <struct name="HelloWorld">
        <member name="sender" type="string" key="true" stringMaxLength="MAX_NAME_LEN"/>
        <member name="message" type="string" stringMaxLength="MAX_MSG_LEN"/>
        <member name="count" type="long"/>
    </struct>
</types>' http://<host>[:<port>]/dds/rest1/types

6.1.2. Listing Types

You can check that the types were loaded correctly by calling GET on /types:

Listing 6.4 Listing Types—HTTP Request
GET /dds/rest1/types HTTP/1.1
Host: <host>[:<port>]
Cache-Control: no-cache
Listing 6.5 Listing Types—Curl Example
curl -X GET -H "Cache-Control:no-cache" http://<host>[:<port>]/dds/rest1/types

6.1.3. Creating Applications

In Web Integration Service, applications are aggregations of DomainParticipants with a common goal. DomainParticipants may:

  • Register types—the <register_type> tag specifies a type definition that will be registered in the DomainParticipant.
  • Create Topics—the <topic> tag specifies a Topic by associating it with a <register_type> that contains the type information.
  • Create Publishers—the <publisher> tag specifies a publisher that will be registered in the DomainPartipant. Publishers can create DataWriters using the <data_writer> tag.
  • Create Subscribers—the <subscriber> tag specifies a Subscriber that will be registered in the DomainParticipant. Subscribers can create DataReaders using the <data_reader> tag.

Our example Application, which we will call ExampleApplication, defines a single DomainParticipant named MyParticipant. This participant operates in Domain 0 and:

  • Registers HelloWorldType, which refers to the HelloWorld type posted before.
  • Creates HelloWorldTopic, which is associated with the registered HelloWorldType.
  • Creates a Publisher called MyPublisher, which creates a DataWriter of HelloWorldTopic called HelloWorldWriter.
  • Creates a Subscriber called MySubscriber, which creates a DataReader of HelloWorldTopic called HelloWorldReader.

Here is the XML representation of ExampleApplication:

Listing 6.6 Creating Applications
<application name="ExampleApplication">
    <domain_participant name="MyParticipant" domain_id="0">
        <register_type name="HelloWorldType" type_ref="HelloWorld"/>
        <topic name="HelloWorldTopic" register_type_ref="HelloWorldType"/>
        <publisher name="MyPublisher">
            <data_writer name="HelloWorldWriter"
                    topic_ref="HelloWorldTopic"/>
        </publisher>
        <subscriber name="MySubscriber">
            <data_reader name="HelloWorldReader" topic_ref="HelloWorldTopic"/>
        </subscriber>
    </domain_participant>
</application>

To create ExampleApplication, along with all its contained entities, we must call POST on /applications and pass in the XML representation of the application in the body of the HTTP request:

Listing 6.7 Creating Applications—HTTP Request
POST /dds/rest1/applications HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 553
Cache-Control: no-cache

<application name="ExampleApplication">
   <domain_participant name="MyParticipant" domain_id="0">
       <register_type name="HelloWorldType" type_ref="HelloWorld"/>
       <topic name="HelloWorldTopic" register_type_ref="HelloWorldType"/>
       <publisher name="MyPublisher">
           <data_writer name="HelloWorldWriter" topic_ref="HelloWorldTopic"/>
       </publisher>
       <subscriber name="MySubscriber">
           <data_reader name="HelloWorldReader" topic_ref="HelloWorldTopic"/>
       </subscriber>
  </domain_participant>
</application>
Listing 6.8 Creating Applications—Curl Example
curl -X POST -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" -d '<application name="ExampleApplication">
   <domain_participant name="MyParticipant" domain_id="0">
       <register_type name="HelloWorldType" type_ref="HelloWorld"/>
       <topic name="HelloWorldTopic" register_type_ref="HelloWorldType"/>
       <publisher name="MyPublisher">
           <data_writer name="HelloWorldWriter" topic_ref="HelloWorldTopic"/>
       </publisher>
       <subscriber name="MySubscriber">
           <data_reader name="HelloWorldReader" topic_ref="HelloWorldTopic"/>
       </subscriber>
   </domain_participant>
</application>' http://<host>[:<port>]/dds/rest1/applications

To check that the defined DomainParticipants, Publishers, Subscribers, DataWriters, and DataReaders were successfully created, call GET on:

  • /applications/ExampleApplication/domain_participants,
  • /applications/ExampleApplication/domain_participants/MyParticipant/publishers
  • /applications/ExampleApplication/domain_participants/MyParticipant/subscribers,
  • /applications/ExampleApplication/domain_participants/MyParticipant/publishers/MyPublisher/data_writers, or
  • /applications/ExampleApplication/domain_participants/MyParticipant/subscribers/MySubsriber/data_readers, respectively.

For instance, to list all the DataWriters within MyPublisher, call:

Listing 6.9 Listing DataWriters—HTTP Request
GET /dds/rest1/applications/ExampleApplication/domain_participants/MyParticipant/publishers/MyPublisher/data_writers HTTP/1.1
Host: <host>[:<port>]
Cache-Control: no-cache
Listing 6.10 Listing DataWriters—Curl Example
curl -X GET -H "Cache-Control:no-cache" http://<host>[:<port>]/dds/rest1/applications/ExampleApplication/domain_participants/MyParticipant/publishers/MyPublisher/data_writers

6.1.4. Sending and Receiving Samples

6.1.4.1. Sending Samples

Once the DataWriter is available, you can start writing data samples. The XML representation of a HelloWorldType data sample follows this structure:

Listing 6.11 Sending Samples
<data>
    <sender>Fernando</sender>
    <message>Hello World!</message>
    <count>0</count>
</data>

To write a new data sample, call POST on /applications/ExampleApplication/domain_participants/MyParticipant/publishers/MyPublisher/data_writers/HelloWorldWriter and pass in the XML representation of the data sample:

Listing 6.12 Sending Samples—HTTP Request
POST /dds/rest1/applications/ExampleApplication/domain_participants/MyParticipant/publishers/MyPublisher/data_writers/HelloWorldWriter HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 101
Cache-Control: no-cache

<data>
    <sender>Fernando</sender>
    <message>Hello World!</message>
    <count>0</count>
</data>
Listing 6.13 Sending Samples—Curl Example
curl -X POST -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" -d '<data>
    <sender>Fernando</sender>
    <message>Hello World!</message>
    <count>0</count>
</data>' http://<host>[:<port>]/dds/rest1/applications/ExampleApplication/domain_participants/MyParticipant/publishers/MyPublisher/data_writers/HelloWorldWriter

6.1.4.2. Receiving Samples

To read the samples available on the DataReader’s cache, call GET on /applications/ExampleApplication/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers:

Listing 6.14 Receiving Samples—HTTP Request
GET /dds/rest1/applications/ExampleApplication/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers/HelloWorldReader HTTP/1.1
Host: <host>[:<port>]
Cache-Control: no-cache
Listing 6.15 Receiving Samples—Curl Example
curl -X GET -H "Cache-Control:no-cache" http://<host>[:<port>]/dds/rest1/applications/ExampleApplication/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers/HelloWorldReader

Response

The response is a sequence with the samples read, which includes sample information (i.e., information pertaining to the associated Data instance sample) and sample data (i.e., the actual received data):

Listing 6.16 Receiving Samples—HTTP Response
HTTP/1.1 200 Samples read
Content-Type: application/dds-web+xml
Cache-Control: no-cache
Content-Length: 537
Date: Fri, 04 Mar 2016 18:50:35 GMT

<read_sample_seq>
    <sample>
        <read_sample_info>
            <source_timestamp>
                <sec>1457117216</sec>
                <nanosec>260702000</nanosec>
            </source_timestamp>
            <valid_data>true</valid_data>
            <instance_handle>
                580BA4179B1A6D6B4CD7CE4F54B3B63C
            </instance_handle>
            <instance_state>ALIVE</instance_state>
            <sample_state>NOT_READ</sample_state>
            <view_state>NEW</view_state>
        </read_sample_info>
        <data>
            <sender>Fernando</sender>
            <message>Hello World!</message>
            <count>0</count>
        </data>
    </sample>
</read_sample_seq>

6.2. Shapes Demo

In the previous example, we started off with an embedded empty configuration to which—using the REST API—we added an application and different DDS entities to send and receive HelloWorldTopic data samples. In this example, we will use another embedded configuration that contains predefined entities to communicate with RTI Shapes Demo.

The embedded shapesDemoTutorial configuration can be found in the following configuration file: $NDDSHOME/resource/xml/RTI_WEB_INTEGRATION_SERVICE.xml. Let’s analyze the different components it contains.

6.2.1. Types Definition

The first thing you will find in RTI_WEB_INTEGRATION_SERVICE.xml is the definition of a data type called ShapeType. This is the type that all the topics that RTI Shapes Demo publishes and subscribes to (i.e., Square, Triangle, and Circle) are associated with. Here is its XML representation:

Listing 6.17 Types Definition
<types>
   <const name="MAX_COLOR_LEN" type="long" value="128"/>
   <struct name="ShapeType">
       <member name="color" type="string" stringMaxLength="128" key="true"/>
       <member name="x" type="long"/>
       <member name="y" type="long"/>
       <member name="shapesize" type="long"/>
   </struct>
</types>

6.2.2. Domain Library

In RTI_WEB_INTEGRATION_SERVICE.xml you will also find a domain library and a domain. Domain libraries provide a way to organize different template domains that can be used in the definition of DomainParticipants. Domains represent data spaces where information can be shared by means of reading and writing the same Topics (which need to be associated with a registered data type). Therefore, in a <domain> tag you can specify Topics and their data types.

Our domain library contains a ShapesDomain that pre-registers ShapeType and creates a Square topic associated with it. DomainParticipants referring to the ShapesDomainLibrary::ShapeDomain domain will automatically instantiate these entities upon creation.

Here is the XML representation of ShapesDomainLibrary, as defined in RTI_WEB_INTEGRATION_SERVICE.xml:

Listing 6.18 Domain Library Definition
<domain_library name="ShapesDomainLibrary">
    <domain name="ShapesDomain" domain_id="0">
        <register_type name="ShapeType" type_ref="ShapeType" />
        <topic name="Square" register_type_ref="ShapeType" />
    </domain>
</domain_library>

6.2.3. Shapes Demo Configuration

The shapesDemoTutorial configuration in RTI_WEB_INTEGRATION_SERVICE.xml also contains an application called ShapesDemoApp. This application creates a single DomainParticipant called MyParticipant using the MyDomainLibrary::ShapeDomain domain. This significantly reduces the entities that need to be defined (i.e., we do not need to register ShapeType or create the Square topic). MyParticipant creates both a Publisher and a Subscriber, which create a Square DataWriter, and a Square DataReader, respectively.

Here is the XML representation of ShapesDemo as defined in RTI_WEB_INTEGRATION_SERVICE.xml:

Listing 6.19 Shapes Demo Tutorial Configuration
<web_integration_service name="shapesDemoTutorial">
    <application name="ShapesDemoApp">
        <domain_participant name="MyParticipant"
            domain_ref="ShapesDomainLibrary::ShapesDomain">
            <publisher name="MyPublisher">
                <data_writer name="MySquareWriter" topic_ref="Square" />
            </publisher>
            <subscriber name="MySubscriber">
                <data_reader name="MySquareReader" topic_ref="Square" />
            </subscriber>
        </domain_participant>
    </application>
</web_integration_service>

To load the whole system definition, start Web Integration Service and specify the shapesDemoTutorial configuration, like this:

$NDDSHOME/bin/rtiwebintegrationservice -cfgName shapesDemoTutorial

Web Integration Service will instantiate all the applications under shapesDemoTutorial and their contained entities. You can check that the MyParticipant has been created by calling GET on /applications/ShapesDemoApp/domain_participants:

Listing 6.20 Shapes Demo Configuration—Listing DomainParticipants HTTP Request
GET /dds/rest1/applications/ShapesDemoApp/domain_participants HTTP/1.1
Host: <host>[:<port>]
Cache-Control: no-cache
Listing 6.21 Shapes Demo Configuration—Listing DomainParticipants Curl Example
curl -X GET -H "Cache-Control:no-cache" http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants

6.2.3.1. Sending and Receiving Square Topics

Sending a Square

You can use the instantiated DataWriter to start writing Square samples. The XML representation of a ShapeType data sample follows this structure:

Listing 6.22 Sending a Square—Sample Definition
<data>
    <color>YELLOW</color>
    <x>100</x>
    <y>150</y>
    <shapesize>30</shapesize>
</data>

To write a new data sample, do a POST on /applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers/MySquareWriter and pass in the XML representation of the data sample:

Listing 6.23 Sending a Square—HTTP Request
POST /dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers/MySquareWriter HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 110
Cache-Control: no-cache

<data>
    <color>YELLOW</color>
    <x>100</x>
    <y>150</y>
    <shapesize>30</shapesize>
</data>
Listing 6.24 Sending a Square—Curl Example
curl -X POST -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" -d '<data>
    <color>YELLOW</color>
    <x>100</x>
    <y>150</y>
    <shapesize>30</shapesize>
</data>' http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers/MySquareWriter

If you subscribe to Squares on Domain 0 using RTI Shapes Demo and publish the sample again, you should see a new yellow square in position (100,150).

Receiving Squares

To read samples using Web Integration Service, call GET on /applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers/MySquareReader:

Listing 6.25 Receiving a Square—HTTP Request
GET /dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers/MySquareReader HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Cache-Control: no-cache
Listing 6.26 Receiving a Square—Curl Example
curl -X GET -H "Cache-Control:no-cache" http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers/MySquareReader

Response

Listing 6.27 Receiving a Square—HTTP Response
HTTP/1.1 200 Samples read
Content-Type: application/dds-web+xml
Cache-Control: no-cache
Content-Length: 528
Date: Fri, 04 Mar 2016 18:52:45 GMT

<read_sample_seq>
    <sample>
        <read_sample_info>
            <source_timestamp>
                <sec>1457117555</sec>
                <nanosec>247519000</nanosec>
            </source_timestamp>
            <valid_data>true</valid_data>
            <instance_handle>
                9ED0E8B29F0249BECF6B24567D3B0DA9
            </instance_handle>
            <instance_state>ALIVE</instance_state>
            <sample_state>NOT_READ</sample_state>
            <view_state>NEW</view_state>
        </read_sample_info>
        <data>
            <color>YELLOW</color>
            <x>100</x>
            <y>150</y>
            <shapesize>30</shapesize>
        </data>
    </sample>
</read_sample_seq>

6.2.4. Creating New Topics, DataWriters, and DataReaders

Sometimes you may want to create new DataWriters and DataReaders for sending and receiving new Topics. For instance, with the current configuration our ShapesDemoApp application can only send and receive Square topics. This section explains how to add new Topics, DataWriters, and DataReaders to our ShapesDemoApp application to be able to send and receive Circles and Triangles as well.

6.2.5. Creating New Topics

6.2.5.1. Creating a Circle

To create a new Circle Topic, call POST on /applications/ShapesDemoApp/domain_participants/MyParticipant/topics and pass in the XML representation of the Topic in the HTTP request. Note that since ShapeType is already registered, you do not need to register it again.

Listing 6.28 Creating a Circle—HTTP Request
POST /dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/topics HTTP/1.1
Host: <host>[:<port>]
Content-Length: 52
Content-Type: application/dds-web+xml
Cache-Control: no-cache

<topic name="Circle" register_type_ref="ShapeType"/>
Listing 6.29 Creating a Circle—Curl Example
curl -X POST -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" -d '<topic name="Circle" register_type_ref="ShapeType"/>' http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/topics

6.2.5.2. Creating a Triangle

To create a Triangle topic, call POST on /applications/ShapesDemoApp/domain_participants/MyParticipant/topics and pass in the XML representation of the Topic in the HTTP request:

Listing 6.30 Creating a Triangle—HTTP Request
POST /dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/topics HTTP/1.1
Host: <host>[:<port>]
Content-Length: 54
Content-Type: application/dds-web+xml
Cache-Control: no-cache

<topic name="Triangle" register_type_ref="ShapeType"/>
Listing 6.31 Creating a Triangle—Curl Example
curl -X POST -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" -d '<topic name="Triangle" register_type_ref="ShapeType"/>' http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/topics

6.2.6. Creating New DataWriters and DataReaders

Once you have created the Circle and Triangle Topics, you can create DataWriters and DataReaders for each Topic by calling POST on /applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers and /applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers, respectively, and passing in their XML representations in the body of the HTTP request.

6.2.6.1. Creating a Circle DataWriter

Listing 6.32 Creating a Circle DataWriter—HTTP Request
POST /dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 56
Cache-Control: no-cache

<data_writer name="MyCircleWriter" topic_ref="Circle" />
Listing 6.33 Creating a Circle DataWriter—Curl Example
curl -X POST -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" -d '<data_writer name="MyCircleWriter" topic_ref="Circle" />' http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers

6.2.6.2. Creating a Triangle DataWriter

Listing 6.34 Creating a Triangle DataWriter—HTTP Request
POST /dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers HTTP/1.1
Host: <host>[:<port>]
Content-Length: 60
Content-Type: application/dds-web+xml
Cache-Control: no-cache

<data_writer name="MyTriangleWriter" topic_ref="Triangle" />
Listing 6.35 Creating a Triangle DataWriter—Curl Example
curl -X POST -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" -d '<data_writer name="MyTriangleWriter" topic_ref="Triangle" />' http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers

6.2.6.3. Creating a Circle DataReader

Listing 6.36 Creating a Circle DataReader—HTTP Request
POST /dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 52
Cache-Control: no-cache

<data_reader name="MyCircleReader" topic_ref="Circle"/>
Listing 6.37 Creating a Circle DataReader—Curl Example
curl -X POST -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" -d '<data_reader name="MyCircleReader" topic_ref="Circle"/>' http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers

6.2.6.4. Creating a Triangle DataReader

Listing 6.38 Creating a Triangle DataReader—HTTP Request
POST /dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 55
Cache-Control: no-cache

<data_reader name="MyTriangleReader" topic_ref="Triangle/>
Listing 6.39 Creating a Triangle DataReader—Curl Example
curl -X POST -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" -d '<data_reader name="MyTriangleReader" topic_ref="Triangle"/>' http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers

6.2.6.5. Listing New DataReaders and DataWriters

You can check whether the new DataWriters and DataReaders were successfully created by calling GET on their respective resource URLs:

Listing DataWriters

Listing 6.40 Listing DataWriters—HTTP Request
GET /dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Cache-Control: no-cache
Listing 6.41 Listing DataWriters—Curl Example
curl -X GET -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/publishers/MyPublisher/data_writers

Listing DataReaders

Listing 6.42 Listing DataReaders—HTTP Request
GET /dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Cache-Control: no-cache
Listing 6.43 Listing DataReaders—Curl Example
curl -X GET -H "Content-Type:application/dds-web+xml" -H "Cache-Control:no-cache" http://<host>[:<port>]/dds/rest1/applications/ShapesDemoApp/domain_participants/MyParticipant/subscribers/MySubscriber/data_readers

Responses

Listing 6.44 Listing DataWriters—HTTP Response
<data_writer_list>
    <data_writer name="MySquareWriter" />
    <data_writer name="MyCircleWriter" />
    <data_writer name="MyTriangleWriter" />
</data_writer_list>
Listing 6.45 Listing DataReaders—HTTP Response
<data_reader_list>
    <data_reader name="MySquareReader" />
    <data_reader name="MyCircleReader" />
    <data_reader name="MyTriangleReader" />
</data_reader_list>

6.3. More Complex Example

This example shows you how to send and receive samples of more complex data types. We will show you how to write nested structures, sequences, arrays, and enums. We will also explain how to create QoS libraries and QoS profiles to configure QoS settings for different DDS entities.

Just like we did in the Hello World example in Section 6.1, we will start a new instance of Web Integration Service from an empty configuration.

$NDDSHOME/bin/rtiwebintegrationservice -cfgName default

6.3.1. Types Definition

In this example we define a much more complicated type called ComplexType. To load ComplexType, call POST on /types, passing its XML definition in the body of the HTTP request.

Listing 6.46 Defining ComplexType—HTTP Response
POST /dds/rest1/types HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 2475
Cache-Control: no-cache

<types>
    <const name="MAX_COLOR_LEN" type="long" value="255" />
    <typedef name="MYBOOL" type="boolean" />
    <enum name="MyEnum">
        <enumerator name="ACE" value="1" />
        <enumerator name="KING" value="13" />
        <enumerator name="QUEEN" value="12" />
    </enum>
    <struct name="PrimitivesType">
        <member name="aString" type="string" stringMaxLength="MAX_COLOR_LEN" />
        <member name="aLong" type="long" />
        <member name="aShort" type="short" />
        <member name="aUnsignedShort" type="unsignedShort" />
        <member name="aUnsignedLong" type="unsignedLong" />
        <member name="aFloat" type="float" />
        <member name="aDouble" type="double" />
        <member name="aBoolean" type="boolean" />
        <member name="aChar" type="char" />
        <member name="aWchar" type="wchar" />
        <member name="aLongLong" type="longLong" />
        <member name="aUnsignedLongLong" type="unsignedLongLong" />
        <member name="anEnum" type="nonBasic" nonBasicTypeName="MyEnum" />
        <member sequenceMaxLength="3" name="anEnumSeq" type="nonBasic"
            nonBasicTypeName="MyEnum" />
        <member arrayDimensions="3" name="anEnumArr" type="nonBasic"
            nonBasicTypeName="MyEnum" />
    </struct>
    <struct name="ComplexType">
        <member name="aString" type="string" stringMaxLength="MAX_COLOR_LEN" />
        <member name="aLong" type="long" />
        <member name="aShort" type="short" />
        <member name="anOctet" type="octet" />
        <member name="aUnsignedShort" type="unsignedShort" />
        <member name="aUnsignedLong" type="unsignedLong" />
        <member name="aFloat" type="float" />
        <member name="aDouble" type="double" />
        <member name="aBoolean" type="boolean" />
        <member name="aChar" type="char" />
        <member name="aWchar" type="wchar" />
        <member name="aLongLong" type="longLong" />
        <member name="aUnsignedLongLong" type="unsignedLongLong" />
        <member name="anAlias" type="nonBasic" nonBasicTypeName="MYBOOL" />
        <member name="aComplexType" type="nonBasic" nonBasicTypeName="PrimitivesType" />
        <member name="anEnum" type="nonBasic" nonBasicTypeName="MyEnum" />
        <member sequenceMaxLength="3" name="anEnumSeq" type="nonBasic"
            nonBasicTypeName="MyEnum" />
        <member arrayDimensions="3" name="anEnumArr" type="nonBasic"
            nonBasicTypeName="MyEnum" />
    </struct>
</types>
Listing 6.47 Defining ComplexType—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<types>
    <const name="MAX_COLOR_LEN" type="long" value="255"/>
    <typedef name="MYBOOL" type="boolean"/>
    <enum name="MyEnum">
        <enumerator name="ACE" value="1"/>
        <enumerator name="KING" value="13"/>
        <enumerator name="QUEEN" value="12"/>
    </enum>
    <struct name="PrimitivesType">
        <member name="aString" type="string" stringMaxLength="MAX_COLOR_LEN"/>
        <member name="aLong" type="long"/>
        <member name="aShort" type="short"/>
        <member name="aUnsignedShort" type="unsignedShort"/>
        <member name="aUnsignedLong" type="unsignedLong"/>
        <member name="aFloat" type="float"/>
        <member name="aDouble" type="double"/>
        <member name="aBoolean" type="boolean"/>
        <member name="aChar" type="char"/>
        <member name="aWchar" type="wchar"/>
        <member name="aLongLong" type="longLong"/>
        <member name="aUnsignedLongLong" type="unsignedLongLong"/>
        <member name="anEnum" type="nonBasic" nonBasicTypeName="MyEnum"/>
        <member sequenceMaxLength="3" name="anEnumSeq" type="nonBasic"
            nonBasicTypeName="MyEnum"/>
        <member arrayDimensions="3" name="anEnumArr" type="nonBasic"
            nonBasicTypeName="MyEnum"/>
    </struct>
    <struct name="ComplexType">
        <member name="aString" type="string" stringMaxLength="MAX_COLOR_LEN"/>
        <member name="aLong" type="long"/>
        <member name="aShort" type="short"/>
        <member name="anOctet" type="octet"/>
        <member name="aUnsignedShort" type="unsignedShort"/>
        <member name="aUnsignedLong" type="unsignedLong"/>
        <member name="aFloat" type="float"/>
        <member name="aDouble" type="double"/>
        <member name="aBoolean" type="boolean"/>
        <member name="aChar" type="char"/>
        <member name="aWchar" type="wchar"/>
        <member name="aLongLong" type="longLong"/>
        <member name="aUnsignedLongLong" type="unsignedLongLong"/>
        <member name="anAlias" type="nonBasic" nonBasicTypeName="MYBOOL"/>
        <member name="aComplexType" type="nonBasic" nonBasicTypeName="PrimitivesType"/>
        <member name="anEnum" type="nonBasic" nonBasicTypeName="MyEnum"/>
        <member sequenceMaxLength="3" name="anEnumSeq" type="nonBasic"
            nonBasicTypeName="MyEnum"/>
        <member arrayDimensions="3" name="anEnumArr" type="nonBasic"
            nonBasicTypeName="MyEnum"/>
    </struct>
</types>' http://<host>[:<port>]/dds/rest1/types

6.3.2. QoS Libraries and QoS Profiles Definition

The QoS section of the XML file provides a way to define QoS libraries and QoS profiles that can be used to configure different QoS settings in your applications.

In this example, we create a QoS library with an empty QoS profile to provide a placeholder in which QoS settings can be specified. Using this empty profile results in the default DDS QoS being used. To create a new QoS library, call POST on /qos_libraries and pass in its XML representation in the body of the HTTP request:

Listing 6.48 Creating a QoS Library—HTTP Request
POST /dds/rest1/qos_libraries HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 105
Cache-Control: no-cache

<qos_library name="qosLibrary">
    <qos_profile name="DefaultProfile">
    </qos_profile>
</qos_library>
Listing 6.49 Creating a QoS Library—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<qos_library name="qosLibrary">
    <qos_profile name="DefaultProfile">
    </qos_profile>
</qos_library>' http://<host>[:<port>]/dds/rest1/qos_libraries

To create a new QoS profile within the created QoS library, call POST on /qos_libraries/qosLibrary/qos_profiles and pass in its XML representation in the body of the HTTP request.

Listing 6.50 Creating a QoS Profile—HTTP Request
POST /dds/rest1/qos_libraries/qosLibrary/qos_profiles HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 50
Cache-Control: no-cache

<qos_profile name="AnotherProfile">
</qos_profile>
Listing 6.51 Creating a QoS Profile—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<qos_profile name="AnotherProfile">
</qos_profile>' http://<host>[:<port>]/dds/rest1/qos_libraries/qosLibrary/qos_profiles

6.3.3. Application Definition

6.3.3.1. Creating Applications

To illustrate the creation of DDS entities using separate requests, let’s create an empty application to which we will add subsequent elements.

Listing 6.52 Creating a new Application—HTTP Request
POST /dds/rest1/applications HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 40
Cache-Control: no-cache

<application name="ComplexApplication"/>
Listing 6.53 Creating a new Application—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<application name="ComplexApplication"/>' http://<host>[:<port>]/dds/rest1/applications

6.3.3.2. Creating DomainParticipants

We are going to create two DomainParticipants within ComplexApplication: DefaultParticipant and SHMEMParticipant. Each participant inherits from a different QoS profile using the base_name attribute of the <participant_qos> tag. Note that base_name takes the fully qualified name of the QoS profile, i.e., <qos_library>::<qos_profile>.

You can override these values by specifying different QoS settings within the <participant_qos> tag. In this example, we override the value of TransportBuiltinQosPolicy to specify the transports that DomainParticipants register automatically when they are enabled.

Creating DefaultParticipant

Listing 6.54 Creating DefaultParticipant—HTTP Request
POST /dds/rest1/applications/ComplexApplication/domain_participants HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 248
Cache-Control: no-cache

<domain_participant name="DefaultParticipant">
    <participant_qos base_name="qosLibrary::DefaultProfile">
        <transport_builtin>
            <mask>UDPv4 | SHMEM</mask>
        </transport_builtin>
    </participant_qos>
</domain_participant>
Listing 6.55 Creating DefaultParticipant—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<domain_participant name="DefaultParticipant">
    <participant_qos base_name="qosLibrary::DefaultProfile">
        <transport_builtin>
            <mask>UDPv4 | SHMEM</mask>
        </transport_builtin>
    </participant_qos>
</domain_participant>' http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants

Creating SHMEMParticipant

Listing 6.56 Creating SHMEMParticipant—HTTP Request
POST /dds/rest1/applications/ComplexApplication/domain_participants HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 238
Cache-Control: no-cache

<domain_participant name="SHMEMParticipant">
    <participant_qos base_name="qosLibrary::AnotherProfile">
        <transport_builtin>
            <mask>SHMEM</mask>
        </transport_builtin>
    </participant_qos>
</domain_participant>
Listing 6.57 Creating SHMEMParticipant—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<domain_participant name="SHMEMParticipant">
    <participant_qos base_name="qosLibrary::AnotherProfile">
        <transport_builtin>
            <mask>SHMEM</mask>
        </transport_builtin>
    </participant_qos>
</domain_participant>' http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants

6.3.3.3. Deleting DomainParticipants

In the rest of the example we will only be using DefaultParticipant, so we can delete the SHMEMParticipant we just created:

Listing 6.58 Deleting SHMEMParticipant—HTTP Request
DELETE /dds/rest1/applications/ComplexApplication/domain_participants/SHMEMParticipant HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Cache-Control: no-cache
Listing 6.59 Deleting SHMEMParticipant—Curl Example
curl -X DELETE -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '' http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants/SHMEMParticipant

6.3.3.4. Registering Types

Before creating Topics and other DDS entities, we need to register ComplexType.

Listing 6.60 Registering ComplexType—HTTP Request
POST /dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/registered_types HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 57
Cache-Control: no-cache

<register_type name="ComplexType" type_ref="ComplexType"/>
Listing 6.61 Registering ComplexType—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<register_type name="ComplexType" type_ref="ComplexType"/>' http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/registered_types

6.3.3.5. Creating Topics

Now we are going to create a ComplexTopic associated with ComplextType. Call POST on /applications/ComplexApplication/domain_participants/DefaultParticipant /topics and pass in the XML representation of the Topic in the body of the HTTP request. In this case we will modify <topic_qos> to set the ReliabilityQosPolicy kind to RELIABLE_RELIABILITY_QOS:

Listing 6.62 Creating ComplexTopic—HTTP Request
POST /dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/topics HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 235
Cache-Control: no-cache

<topic register_type_ref="ComplexType" name="ComplexTopic">
    <topic_qos base_name="qosLibrary::DefaultProfile">
        <reliability>
            <kind>RELIABLE_RELIABILITY_QOS</kind>
        </reliability>
    </topic_qos>
</topic>
Listing 6.63 Creating ComplexTopic—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache"  -d '<topic register_type_ref="ComplexType" name="ComplexTopic">
    <topic_qos base_name="qosLibrary::DefaultProfile">
        <reliability>
            <kind>RELIABLE_RELIABILITY_QOS</kind>
        </reliability>
    </topic_qos>
</topic>' http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/topics

6.3.3.6. Creating Publishers

To create a new Publisher within DefaultParticipant, call POST on /applications/ComplexApplication/domain_participants/DefaultParticipant/publishers and pass in its XML representation in the body of the HTTP request:

Listing 6.64 Creating ComplexPublisher—HTTP Request
POST /dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/publishers HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 36
Cache-Control: no-cache

<publisher name="ComplexPublisher"/>
Listing 6.65 Creating ComplexPublisher—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<publisher name="ComplexPublisher"/>' http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/publishers

6.3.3.7. Creating DataWriters

To create a DataWriter of ComplexTopic, call POST on /applications/ComplexApplication/domain_participants/DefaultParticipant/publishers/ComplexPublisher/data_writers and pass in its XML representation in the body of the HTTP request. In this case we will modify the DataWriter QoS and set the ReliabilityQosPolicy kind to RELIABLE_RELIABILITY_QOS:

Listing 6.66 Creating ComplexDW—HTTP Request
POST /dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/publishers/ComplexPublisher/data_writers HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 247
Cache-Control: no-cache

<data_writer topic_ref="ComplexTopic" name="ComplexDW">
    <datawriter_qos base_name="qosLibrary::AnotherProfile">
        <reliability>
            <kind>RELIABLE_RELIABILITY_QOS</kind>
        </reliability>
    </datawriter_qos>
</data_writer>
Listing 6.67 Creating ComplexDW—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<data_writer topic_ref="ComplexTopic" name="ComplexDW">
    <datawriter_qos base_name="qosLibrary::AnotherProfile">
        <reliability>
            <kind>RELIABLE_RELIABILITY_QOS</kind>
        </reliability>
    </datawriter_qos>
</data_writer>' http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/publishers/ComplexPublisher/data_writers

6.3.3.8. Creating Subscribers

To create a new Subscriber within DefaultParticipant, call POST on /applications/ComplexApplication/domain_participants/DefaultParticipant/subscribers and pass in its XML representation in the body of the HTTP request:

Listing 6.68 Creating ComplexSubscriber—HTTP Request
POST /dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/subscribers HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 38
Cache-Control: no-cache

<subscriber name="ComplexSubscriber"/>
Listing 6.69 Creating ComplexSubscriber—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<subscriber name="ComplexSubscriber"/>' http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/subscribers

6.3.3.9. Creating DataReaders

To create a DataReader of ComplexTopic, call POST on /applications/ComplexApplication/domain_participants/DefaultParticipant/subscribers/ComplexSubscriber/data_readers and pass in its XML representation in the body of the HTTP request. In this case we will modify the DataReader QoS and set the ReliabilityQosPolicy kind to RELIABLE_RELIABILITY_QOS:

Listing 6.70 Creating ComplexDR—HTTP Request
POST /dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/subscribers/ComplexSubscriber/data_readers HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 276
Cache-Control: no-cache

<data_reader topic_ref="ComplexTopic" name="ComplexDR">
    <datareader_qos>
        <reliability>
            <kind>RELIABLE_RELIABILITY_QOS</kind>
        </reliability>
        <history>
            <depth>10</depth>
        </history>
    </datareader_qos>
</data_reader>
Listing 6.71 Creating ComplexDR—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<data_reader topic_ref="ComplexTopic" name="ComplexDR">
    <datareader_qos>
        <reliability>
            <kind>RELIABLE_RELIABILITY_QOS</kind>
        </reliability>
        <history>
            <depth>10</depth>
        </history>
    </datareader_qos>
</data_reader>
' http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/subscribers/ComplexSubscriber/data_readers

6.3.4. Sending and Receiving Complex Samples

6.3.4.1. Sending Samples

Once the DataWriter is available, you can start writing ComplexType data samples. The XML representation of a ComplexType data sample follows the structure of the previous examples, but introduces the concept of complex members (e.g., nested structs, sequences, or arrays). We also introduce the concept of enums. Note that when writing enums you need to provide the integer representation of the enumeration value.

To write a new ComplexType data sample, POST the XML sample representation on /applications/ComplexApplication/domain_participants/DefaultParticipant/publishers/ComplexPublisher/data_writers/ComplexDW.

Listing 6.72 Writing a ComplexType Data Sample—HTTP Request
POST /dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/publishers/ComplexPublisher/data_writers/ComplexDW HTTP/1.1
Host: <host>[:<port>]
Content-Type: application/dds-web+xml
Content-Length: 1296
Cache-Control: no-cache

<data>
  <aString>This is a string!</aString>
  <aLong>-123456789</aLong>
  <aShort>125</aShort>
  <anOctet>255</anOctet>
  <aUnsignedShort>5</aUnsignedShort>
  <aUnsignedLong>123456789</aUnsignedLong>
  <aFloat>3.14</aFloat>
  <aDouble>3.1592</aDouble>
  <aBoolean>false</aBoolean>
  <aChar>a</aChar>
  <aWchar>&#x007E;</aWchar>
  <aLongLong>-4215479752654469884268442</aLongLong>
  <aUnsignedLongLong>14</aUnsignedLongLong>
  <anEnumSeq>
    <item>KING</item>
    <item>QUEEN</item>
    <item>ACE</item>
  </anEnumSeq>
  <anEnumArr>
    <item>ACE</item>
    <item>QUEEN</item>
    <item>KING</item>
  </anEnumArr>
  <aComplexType>
    <aString>Another string!</aString>
    <aLong>-123456789</aLong>
    <aShort>125</aShort>
    <aUnsignedShort>5</aUnsignedShort>
    <aUnsignedLong>123456789</aUnsignedLong>
    <aFloat>3.14</aFloat>
    <aDouble>3.1592</aDouble>
    <aBoolean>true</aBoolean>
    <aChar>a</aChar>
    <aWchar>&#x007E;</aWchar>
    <aLongLong>-4215479752654469884268442</aLongLong>
    <aUnsignedLongLong>21</aUnsignedLongLong>
    <anEnumSeq>
      <item>KING</item>
      <item>QUEEN</item>
      <item>ACE</item>
    </anEnumSeq>
    <anEnumArr>
      <item>ACE</item>
      <item>QUEEN</item>
      <item>KING</item>
    </anEnumArr>
  </aComplexType>
  <anEnum>12</anEnum>
</data>
Listing 6.73 Writing a ComplexType Data Sample—Curl Example
curl -X POST -H "Content-Type: application/dds-web+xml" -H "Cache-Control: no-cache" -d '<data>
  <aString>This is a string!</aString>
  <aLong>-123456789</aLong>
  <aShort>125</aShort>
  <anOctet>255</anOctet>
  <aUnsignedShort>5</aUnsignedShort>
  <aUnsignedLong>123456789</aUnsignedLong>
  <aFloat>3.14</aFloat>
  <aDouble>3.1592</aDouble>
  <aBoolean>false</aBoolean>
  <aChar>a</aChar>
  <aWchar>&#x007E;</aWchar>
  <aLongLong>-4215479752654469884268442</aLongLong>
  <aUnsignedLongLong>14</aUnsignedLongLong>
  <anEnumSeq>
    <item>KING</item>
    <item>QUEEN</item>
    <item>ACE</item>
  </anEnumSeq>
  <anEnumArr>
    <item>ACE</item>
    <item>QUEEN</item>
    <item>KING</item>
  </anEnumArr>
  <aComplexType>
    <aString>Another string!</aString>
    <aLong>-123456789</aLong>
    <aShort>125</aShort>
    <aUnsignedShort>5</aUnsignedShort>
    <aUnsignedLong>123456789</aUnsignedLong>
    <aFloat>3.14</aFloat>
    <aDouble>3.1592</aDouble>
    <aBoolean>true</aBoolean>
    <aChar>a</aChar>
    <aWchar>&#x007E;</aWchar>
    <aLongLong>-4215479752654469884268442</aLongLong>
    <aUnsignedLongLong>21</aUnsignedLongLong>
    <anEnumSeq>
      <item>KING</item>
      <item>QUEEN</item>
      <item>ACE</item>
    </anEnumSeq>
    <anEnumArr>
      <item>ACE</item>
      <item>QUEEN</item>
      <item>KING</item>
    </anEnumArr>
  </aComplexType>
  <anEnum>12</anEnum>
</data>' http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/publishers/ComplexPublisher/data_writers/ComplexDW

6.3.4.2. Receiving Samples

Request

To read samples, call `GET` on /applications/ComplexApplication/domain_participants/DefaultParticipant/subscribers/ComplexSubscriber/data_readers/ComplexDR:

Listing 6.74 Reading ComplexType Data Samples—HTTP Request
GET /dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/subscribers/ComplexSubscriber/data_readers/ComplexDR HTTP/1.1
Host:  <host>[:<port>]
Cache-Control: no-cache
Listing 6.75 Reading ComplexType Data Samples—Curl Example
curl -X GET -H "Cache-Control: no-cache" http://<host>[:<port>]/dds/rest1/applications/ComplexApplication/domain_participants/DefaultParticipant/subscribers/ComplexSubscriber/data_readers/ComplexDR

Response

The response contains the sequence of read samples, including sample information and sample data:

Listing 6.76 Reading ComplexType Data Samples—HTTP Response
HTTP/1.1 200 Samples read
Content-Type: application/dds-web+xml
Cache-Control: no-cache
Content-Length: 1535
Date: Fri, 04 Mar 2016 19:00:36 GMT

<read_sample_seq>
    <sample>
        <read_sample_info>
            <source_timestamp>
                <sec>1457118026</sec>
                <nanosec>979762998</nanosec>
            </source_timestamp>
            <valid_data>true</valid_data>
            <instance_handle>
                00000000000000000000000000000000
            </instance_handle>
            <instance_state>ALIVE</instance_state>
            <sample_state>NOT_READ</sample_state>
            <view_state>NEW</view_state>
        </read_sample_info>
        <data>
            <aString>This is a string!</aString>
            <aLong>-123456789</aLong>
            <aShort>125</aShort>
            <anOctet>255</anOctet>
            <aUnsignedShort>5</aUnsignedShort>
            <aUnsignedLong>123456789</aUnsignedLong>
            <aFloat>3.140000</aFloat>
            <aDouble>3.159200</aDouble>
            <aBoolean>false</aBoolean>
            <aChar>a</aChar>
            <aWchar>&#x007E;</aWchar>
            <aLongLong>-9223372036854775808</aLongLong>
            <aUnsignedLongLong>14</aUnsignedLongLong>
            <anAlias>false</anAlias>
            <aComplexType>
                <aString>Another string!</aString>
                <aLong>-123456789</aLong>
                <aShort>125</aShort>
                <aUnsignedShort>5</aUnsignedShort>
                <aUnsignedLong>123456789</aUnsignedLong>
                <aFloat>3.140000</aFloat>
                <aDouble>3.159200</aDouble>
                <aBoolean>true</aBoolean>
                <aChar>a</aChar>
                <aWchar>&#x007E;</aWchar>
                <aLongLong>-9223372036854775808</aLongLong>
                <aUnsignedLongLong>21</aUnsignedLongLong>
                <anEnum>1</anEnum>
                <anEnumSeq>
                    <item>KING</item>
                    <item>QUEEN</item>
                    <item>ACE</item>
                </anEnumSeq>
                <anEnumArr>
                    <item>ACE</item>
                    <item>QUEEN</item>
                    <item>KING</item>
                </anEnumArr>
            </aComplexType>
            <anEnum>12</anEnum>
            <anEnumSeq>
                <item>KING</item>
                <item>QUEEN</item>
                <item>ACE</item>
            </anEnumSeq>
            <anEnumArr>
                <item>ACE</item>
                <item>QUEEN</item>
                <item>KING</item>
            </anEnumArr>
        </data>
    </sample>
</read_sample_seq>

6.4. Simple JavaScript Client Application

This example illustrates how to subscribe to DDS data with a simple JavaScript application running in a browser. In particular, the example implements a simplified version of RTI Shapes Demo where samples are drawn on a canvas using Fabric—a simple JavaScript framework.

The example code can be found under <path_to_examples>/web_integration_service/examples/simple_shapes_demo.

Note

See Section 1.2 to learn about the location of <path_to_examples> on your platform.

6.4.1. Running the Example

To run the example, open a terminal and enter the following command:

$NDDSHOME/bin/rtiwebintegrationservice \
    -cfgFile $path_to_examples/web_integration_service/examples/simple_shapes_demo/simple_shapes_demo.xml \
    -cfgName simpleShapesDemo \
    -documentRoot $path_to_examples/web_integration_service \
    -enableKeepAlive yes

Where:

  • The -cfgFile argument loads the appropriate configuration file into Web Integration Service.
  • The -cfgName argument specifies the configuration to be instantiated—in this case simpleShapesDemo—which starts the ShapesDemoApp. This application instantiates a DomainParticipant with DataReaders to read to all shape topics (i.e., Squares, Circles, and Triangles).
  • The -documentRoot argument specifies the folder that Web Integration Service’s web server will provide when accessing the default URL. That is http://<host>:8080. This specific example can then be found under http://<hostname>:8080/examples/simple_shapes_demo/js.
  • The -enablekeepAlive argument configures the service to keep open the underlying TCP connection between client and server between subsequent requests and responses when possible.

6.4.1.1. Running RTI Shapes Demo

Once you have started Web Integration Service, you can open RTI Shapes Demo and start publishing shapes on Domain 0.

6.4.1.2. Running Simple Shapes Demo JavaScript Client

Open a browser and navigate to http://<host>:8080/examples/simple_shapes_demo/js. There you will find all the shapes that are being published.

Web Shapes Demo Screenshot

Figure 6.1 Web Shapes Demo Screenshot

6.4.2. Example Code

6.4.2.1. Client Application

Listing 6.77 Client Application—examples/simple_shapes_demo/js/shapes_demo.js
/*
 * (c) 2016-2017 Copyright, Real-Time Innovations, Inc.  All rights reserved.
 * RTI grants Licensee a license to use, modify, compile, and create derivative
 * works of the Software.  Licensee has the right to distribute object form
 * only for use with RTI products.  The Software is provided "as is", with no
 * warranty of any type, including any warranty for fitness for any purpose.
 * RTI is under no obligation to maintain or support the Software.  RTI shall
 * not be liable for any incidental or consequential damages arising out of the
 * use or inability to use the software.
 */

var rti = rti || {};

/**
 * @namespace rti.shapesdemo
 */
rti.shapesdemo = {
    /**
     * Sets up a new canvas in a <div id="shapesDemoCanvas">. This method
     * needs to be called before reading or drawing shapes.
     */
    setupScenario: function() {
        rti.shapesdemo.canvas = new fabric.Canvas(
            'shapesDemoCanvas',
            {
                hoverCursor: 'pointer',
                perPixelTargetFind: true,
                targetFindTolerance: 5,
                backgroundImage: '../../../../resources/img/rti_background.png'
            }
        );
    },

    /**
     * Sets up the enviroment for reading shapes. The method will call the
     * methods that draw shapes at 33 ms intervals.
     */
    readShapes: function() {
        var squareReaderUrl =
            "/dds/rest1/applications/ShapesDemoApp" +
            "/domain_participants/MyParticipant" +
            "/subscribers/MySubscriber" +
            "/data_readers/MySquareReader";
        var triangleReaderUrl =
            "/dds/rest1/applications/ShapesDemoApp" +
            "/domain_participants/MyParticipant" +
            "/subscribers/MySubscriber" +
            "/data_readers/MyTriangleReader";
        var circleReaderUrl =
            "/dds/rest1/applications/ShapesDemoApp" +
            "/domain_participants/MyParticipant" +
            "/subscribers/MySubscriber" +
            "/data_readers/MyCircleReader";

        var shapesDemoIntervalPeriod = 33; // in milliseconds

        // Call drawShape() for Squares, Circles, and Triangles every
        // shapesDemoIntervalPeriod, passing the resulting data 
        // for reading new samples of the appropriate topic in json format
        // without deleting the samples from the Reader's cache.
        setInterval(function(){
            // Read Squares
            $.getJSON(
                squareReaderUrl,
                {
                    sampleFormat: "json",
                    removeFromReaderCache: "false"
                },
                function(data) {
                    rti.shapesdemo.drawShape(data, "Square");
                }
            );

            // Read Triangles
            $.getJSON(
                triangleReaderUrl,
                {
                    sampleFormat: "json",
                    removeFromReaderCache: "false"
                },
                function(data) {
                    rti.shapesdemo.drawShape(data, "Triangle");
                }
            );

            // Read Circles
            $.getJSON(
                circleReaderUrl,
                {
                    sampleFormat: "json",
                    removeFromReaderCache: "false"
                },
                function(data) {
                    rti.shapesdemo.drawShape(data, "Circle");
                }
            );
        }, shapesDemoIntervalPeriod);
    },

    /**
     * Draws a sequence of shapes given their shape kind (i.e., whether it is
     * a Circle, Square, or a Triangle).
     * @param sampleSeq Sequence of samples to be drawn.
     * @param shapeKind kind of shape to draw. Valid values are 'Circle',
     * 'Square', or 'Triangle'.
     */
    drawShape: function(sampleSeq, shapeKind) {
        sampleSeq.forEach(function(sample, i, samples) {
            // Process metadata
            var validData = sample.read_sample_info.valid_data;
            var instanceHandle = sample.read_sample_info.instance_handle;
            var instanceState  = sample.read_sample_info.instance_state;

            // If we received an invalid data sample, and the instance state
            // is != ALIVE, then the instance has been either disposed or
            // unregistered and we remove the shape from the canvas.
            if (!validData) {
                if (instanceState != "ALIVE") {
                    rti.shapesdemo.canvas.getObjects().every(
                        function (element, j, array) {
                            if (element.uid.instanceHandle == instanceHandle
                                && element.uid.topic == shapeKind) {
                                element.remove();
                                rti.shapesdemo.canvas.renderAll();
                                return false;
                            }
                            return true;
                        }
                    );
                    return true;
                }
                return true;
            }

            // Process sample data (i.e., color, shapesSize, and position
            // of the received shape). If the color is not in the list of
            // supported colors, we assign it blue.
            var color;
            if (rti.shapesdemo.shapeColors.hasOwnProperty(sample.data.color)) {
                color = rti.shapesdemo.shapeColors[sample.data.color];
            } else {
                color = rti.shapesdemo.shapeColors.BLUE;
            }

            var shapeSize = sample.data.shapesize;
            var x = sample.data.x - shapeSize/2;
            var y = sample.data.y - shapeSize/2;

            // Look for the shape received on the canvas
            var shape = undefined;
            for (var i = 0; i < rti.shapesdemo.canvas.getObjects().length; i++){
                var currentElement = rti.shapesdemo.canvas.getObjects()[i];
                if (currentElement.uid.instanceHandle == instanceHandle
                        && currentElement.uid.topic == shapeKind) {
                    shape = currentElement;
                    break;
                }
            }

            // If it is not there, we need to create a new shape in the
            // received position. Otherwise, update the existing shape's
            // position.
            if (shape == undefined) { // Add new shape in the position
                var newShape;
                if (shapeKind == "Square") {
                	newShape = new fabric.Rect({
                	    left: x,
                	    top: y,
                	    originX: 'left',
                	    originY: 'top',
                	    width: shapeSize,
                	    height: shapeSize,
                	    angle: 0,
                            fill: color,
                            transparentCorners: false,
                            selectable: false
                        });
                } else if (shapeKind == "Triangle") {
                    newShape = new fabric.Triangle({
                	    left: x,
                	    top: y,
                	    originX: 'left',
                	    originY: 'top',
                	    width: shapeSize,
                	    height: shapeSize,
                	    angle: 0,
                	    fill: color,
                            transparentCorners: false,
                            selectable: false
                	});
                } else if (shapeKind == "Circle"){
                    newShape = new fabric.Circle({
                	    left: x,
                	    top: y,
                	    originX: 'left',
                	    originY: 'top',
                	    radius: shapeSize/2,
                	    angle: 0,
                	    fill: color,
                            transparentCorners: false,
                            selectable: false
                	});
                }
                newShape.uid = {
                    "instanceHandle": instanceHandle,
                    "topic": shapeKind
                }
                rti.shapesdemo.canvas.add(newShape);
            } else { // Update position of existing shape
                shape.setLeft(x).setCoords();
                shape.setTop(y).setCoords();
                rti.shapesdemo.canvas.renderAll();
            }
            return true;
        });
    }
}

/**
 * Canvas in which we will be drawing all the shapes
 */
rti.shapesdemo.canvas = {};

/**
 * Object with the list of supported colors along with their corresponding
 * color code.
 */
rti.shapesdemo.shapeColors = {
    PURPLE : "#b000ff",
    BLUE: "#0000ff",
    RED: "#ff0000",
    GREEN: "#00ff00",
    YELLOW: "#ffff00",
    CYAN: "#00ffff",
    MAGENTA: "#ff00ff",
    ORANGE: "#ff8200"
};

6.4.2.2. Web Integration Service Configuration File

Listing 6.78 Web Integration Service Configuration File—examples/simple_shapes_demo/simple_shapes_demo.xml
<?xml version="1.0"?>
<!--
    (c) 2016 Copyright, Real-Time Innovations, Inc.  All rights reserved.
    RTI grants Licensee a license to use, modify, compile, and create derivative
    works of the Software.  Licensee has the right to distribute object form only
    for use with RTI products.  The Software is provided "as is", with no warranty
    of any type, including any warranty for fitness for any purpose. RTI is under
    no obligation to maintain or support the Software.  RTI shall not be liable for
    any incidental or consequential damages arising out of the use or inability to
    use the software.
-->

<!-- RTI Data Distribution Service Deployment -->
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/latest/rti_web_integration_service.xsd">

    <!-- This QoS Profile enables a reliable DataReader that will keep only
         the last sample in its cache.
    -->
    <qos_library name="SimpleShapesDemoQoSLib">
        <qos_profile name="SimpleShapesDemoQosProfile" is_default_qos="true">
            <datareader_qos>
                <reliability>
                    <kind>RELIABLE_RELIABILITY_QOS</kind>
                </reliability>
                <history>
                    <depth>10</depth>
                    <kind>KEEP_LAST_HISTORY_QOS</kind>
                </history>
            </datareader_qos>
        </qos_profile>
    </qos_library>

    <!--
        This configuration contains a complete scenario for interacting with RTI
        Shapes Demo. That is, it creates all the necessary Topics, DataWriters,
        and DataReaders to publish and subscribe to Squares, Circles, and
        Triangles. The data types and domains in "MyParticipant" refer to the
        ones defined in resource/xml/RTI_WEB_INTEGRATION_SERVICE.xml.
        Note that this file is automatically loaded by Web Integration Service
        at startup.
    -->
    <web_integration_service name="simpleShapesDemo">
        <application name="ShapesDemoApp">
            <domain_participant name="MyParticipant"
                                domain_ref="ShapesDomainLibrary::ShapesDomain">
                <register_type name="ShapeType" type_ref="ShapeType" />
                <topic name="Square" register_type_ref="ShapeType" />
                <topic name="Circle" register_type_ref="ShapeType" />
                <topic name="Triangle" register_type_ref="ShapeType" />
                <publisher name="MyPublisher">
                    <data_writer name="MySquareWriter" topic_ref="Square" />
                    <data_writer name="MyCircleWriter" topic_ref="Circle" />
                    <data_writer name="MyTriangleWriter" topic_ref="Triangle" />
                </publisher>
                <subscriber name="MySubscriber">
                    <data_reader name="MySquareReader" topic_ref="Square" />
                    <data_reader name="MyCircleReader" topic_ref="Circle" />
                    <data_reader name="MyTriangleReader" topic_ref="Triangle" />
                </subscriber>
            </domain_participant>
        </application>
    </web_integration_service>
</dds>