1

I'm using OpenDDS v3.6, and trying to send a message to a specific DDS peer, one of many. In the IDL, the message structure looks like the following:

module Test
{
#pragma DCPS_DATA_TYPE "Test::MyMessage"
#pragma DCPS_DATA_KEY "Test::MyMessage dest_id"
    struct MyMessage {
        short dest_id;
        string txt;
    };
};

My understanding is that because the data key is unique, this is a new instance of the topic being written to, and any further msgs written w/ the same data key send to this specific instance of the topic. My send code is as follows:

DDS::ReturnCode_t ret;
Test::MyMessage msg;

// populate msg
msg.dest_id = n;

DDS::InstanceHandle_t handle;

handle = msg_writer->register_instance(msg);

ret = msg_writer->write(msg, handle);

So now I need to figure out how to get the receiving peer to read only from this topic instance and not receive all the other messages being sent to other peers. I started with the following, but not sure how to properly select a specific topic instance.

DDS::InstanceHandle_t instance;

status = msg_dr->take_next_instance(spec, si, 1, DDS::ANY_SAMPLE_STATE, 
    DDS::ANY_VIEW_STATE, DDS::ANY_INSTANCE_STATE);

Any help much appreciated.

Ender
  • 1,652
  • 2
  • 25
  • 50

1 Answers1

2

The easiest way to achieve what you are looking for is by using a ContentFilteredTopic. This class is a specialization of the TopicDescription class and allows you to specify an expression (like a SQL WHERE-clause) of the samples that you are interested in.

Suppose you want your DataReader to only receive samples with dest_id equal to 42, then the corresponding code for creating the ContentFilteredTopic would look something like

DDS::ContentFilteredTopic_var cft =
              participant->create_contentfilteredtopic("MyTopic-Filtered",
                                                       topic,
                                                       "dest_id = 42",
                                                       StringSeq());

From there on, you create your DataReader using cft as the parameter for the TopicDescription. The resulting reader will look like a regular DataReader, except that it only receives the desired samples and nothing else. Since the field dest_id happens to be the field that identifies the instance, the end result is that you will only have one instance in your DataReader.

You can check out the DDS specification (section 7.1.2.3.3) or OpenDDS Developer's Guide (section 5.2) for more details.

Reinier Torenbeek
  • 16,669
  • 7
  • 46
  • 69
  • Thanks, I'll change this out to ContentFiltered then. However, is my understanding of topic instances wrong? Whats the purpose of a new instance based on the key if a peer is going to receive all samples of all instances of that type? Can peers not read a single instance? – Ender Apr 20 '15 at 20:55
  • And if I understand the class specialization correctly, this is TopicDecscription, not Topic as you have. So I assume thats just a typo, or please correct me. – Ender Apr 20 '15 at 21:11
  • Your understanding of topic instances might be wrong indeed... The purpose of a new instance based on the key is that each instance of the Topic can have its own CRUD life-cycle. In that light, you can compare a Topic to a database table and the instances to the rows in that table. In some cases, a peer might be interested in all rows (for example, all trucks in a fleet) but in other cases, a peer might be interested in a single row (for example if used for request/reply). – Reinier Torenbeek Apr 20 '15 at 21:45
  • You also asked "Can peers not read a single instance?" -- yes they can, that is what the ContentFilteredTopic is for. Note that read_instance() (and the related instance functions) can be used for reading a single instance out of the pool of instances in a DataReader. This will not avoid the delivery of other instances to the DataReader though. You need the ContentFilteredTopic for that. – Reinier Torenbeek Apr 20 '15 at 21:47
  • You are right about the TopicDescription base class, thanks. I corrected it. – Reinier Torenbeek Apr 20 '15 at 21:48