【问题标题】:Receive messages only from a specific DDS topic instance?只接收来自特定 DDS 主题实例的消息?
【发布时间】:2015-06-26 11:41:56
【问题描述】:

我正在使用 OpenDDS v3.6,并尝试向特定 DDS 对等方发送消息,这是众多对等方之一。在 IDL 中,消息结构如下所示:

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

我的理解是,由于数据键是唯一的,因此这是正在写入的主题的新实例,并且使用相同数据键写入的任何进一步的 msg 都会发送到该主题的此特定实例。我的发送代码如下:

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);

所以现在我需要弄清楚如何让接收对等方仅从该主题实例中读取,而不接收发送给其他对等方的所有其他消息。我从以下开始,但不确定如何正确选择特定主题实例。

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);

非常感谢任何帮助。

【问题讨论】:

    标签: ace data-distribution-service tao


    【解决方案1】:

    最简单的方法是使用ContentFilteredTopic。该类是 TopicDescription 类的特化,允许您指定您感兴趣的示例的表达式(如 SQL WHERE-clause)。

    假设您希望您的 DataReader 仅接收 dest_id 等于 42 的样本,那么用于创建 ContentFilteredTopic 的相应代码将类似于

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

    从那里开始,您使用cft 作为TopicDescription 的参数来创建您的DataReader。生成的阅读器看起来像普通的DataReader,除了它只接收所需的样本而没有其他内容。由于字段 dest_id 恰好是标识实例的字段,最终结果是您的 DataReader 中只有一个实例。

    您可以查看DDS specification(第 7.1.2.3.3 节)或OpenDDS Developer's Guide(第 5.2 节)了解更多详情。

    【讨论】:

    • 谢谢,那我把它改成 ContentFiltered。但是,我对主题实例的理解是错误的吗?如果对等方要接收该类型所有实例的所有样本,那么基于密钥的新实例的目的是什么?同行不能读取单个实例吗?
    • 如果我正确理解了类专业化,这是 TopicDecscription,而不是您所拥有的 Topic。所以我认为这只是一个错字,或者请纠正我。
    • 你对topic实例的理解可能确实是错误的……基于key新建实例的目的是让每个Topic实例都有自己的CRUD生命周期。鉴于此,您可以将主题与数据库表进行比较,将实例与该表中的行进行比较。在某些情况下,对等点可能对所有行感兴趣(例如,车队中的所有卡车),但在其他情况下,对等点可能对单行感兴趣(例如,如果用于请求/回复)。
    • 您还问过“同行不能读取单个实例吗?” -- 是的,他们可以,这就是 ContentFilteredTopic 的用途。请注意,read_instance()(和相关的实例函数)可用于从 DataReader 的实例池中读取单个实例。但是,这不会避免将其他实例传递给 DataReader。为此,您需要 ContentFilteredTopic。
    • 您对 TopicDescription 基类的看法是正确的,谢谢。我更正了。
    猜你喜欢
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-29
    • 2021-12-10
    • 2020-04-23
    • 2019-04-21
    相关资源
    最近更新 更多