Chapter 17 Data Types and DDS Data Samples

Note: Information in this chapter is complemented by information in the RTI Connext Core Libraries Extensible Types Guide.

How data is stored or laid out in memory can vary from language to language, compiler to compiler, operating system to operating system, and processor to processor. This combination of language/compiler/operating system/processor is called a platform. Any modern middleware must be able to take data from one specific platform (say C/gcc 7.3/Linux/Arm v8) and transparently deliver it to another (for example, Java/AdoptOpenJDK 17.0.6/Windows/Pentium). This process is commonly called serialization/deserialization, or marshalling/demarshalling.

Messaging products have typically taken one of two approaches to this problem:

  1. Do nothing. Messages consist only of opaque streams of bytes. The JMS BytesMessage is an example of this approach.
  2. Send everything, every time. Self-describing messages are at the opposite extreme, embedding full reflective information, including data types and field names, with each message. The JMS MapMessage and the messages in TIBCO Rendezvous are examples of this approach.

The “do nothing” approach is lightweight on its surface but forces you, the user of the middleware API, to consider all data encoding, alignment, and padding issues. The “send everything” alternative results in large amounts of redundant information being sent with every packet, impacting performance.

Connext takes an intermediate approach. Just as objects in your application program belong to some data type, DDS data samples sent on the same Connext topic share a data type. This type defines the fields that exist in the DDS data samples and what their constituent types are. The middleware stores and propagates this meta-information separately from the individual DDS data samples, allowing it to propagate DDS samples efficiently while handling byte ordering and alignment issues for you.

To publish and/or subscribe to data with Connext, you will carry out the following steps:

  1. Select a type to describe your data.
  2. You have a number of choices. You can choose one of these options, or you can mix and match them.

    • Use a built-in type provided by the middleware.
    • This option may be sufficient if your data typing needs are very simple. If your data is highly structured, or you need to be able to examine fields within that data for filtering or other purposes, this option may not be appropriate. The built-in types are described in 17.2 Built-in Data Types.

    • Use the RTI Code Generator to define a type at compile-time using a language-independent description language.

      Code generation offers two strong benefits not available with dynamic type definition: (1) it allows you to share type definitions across programming languages, and (2) because the structure of the type is known at compile time, it provides rigorous static type safety.

      The RTI Code Generator accepts input in the following formats:

    • Define a type programmatically at run time.
    • This method may be appropriate for applications with dynamic data description needs: applications for which types change frequently or cannot be known ahead of time. It is described in 17.8.2 Defining New Types.

  3. Register your type with a logical name.
  4. If you've chosen to use a built-in type instead of defining your own, you can omit this step; the middleware pre-registers the built-in types for you.

    This step is described in the 17.8.2 Defining New Types.

  5. Create a Topic using the type name you previously registered.
  6. If you've chosen to use a built-in type instead of defining your own, you will use the API constant corresponding to that type's name.

    Creating and working with Topics is discussed in Chapter 18 Working with Topics.

  7. Create one or more DataWriters to publish your data and one or more DataReaders to subscribe to it.
  8. The concrete types of these objects depend on the concrete data type you've selected, in order to provide you with a measure of type safety.

    Creating and working with DataWriters and DataReaders are described in Part 5: Sending Data with Connext and Chapter 38 Overview of Receiving Data, respectively.

Whether publishing or subscribing to data, you will need to know how to create and delete DDS data samples and how to get and set their fields. These tasks are described in 17.9 Working with DDS Data Samples.