dds:subscribe

订阅者

订阅由DataReader 与Subscriber的关联定义。为了开始接收发布的更新,应用程序在订阅服务器中创建一个新的 DataReader。此 DataReader 将绑定到 描述将要接收的数据类型的主题。然后,DataReader 将开始从与该主题匹配的远程发布接收数据值更新。

当订阅者接收到数据时,它会通知应用程序有新数据可用。然后,应用程序可以使用 DataReader 来获取接收到的数据
在这里插入图片描述
类似于publish,具体操作:

subscribe

Subscriber代表属于它的一个或多个DataReader对象的行为。它作为一个容器,允许在订阅者的订阅者Qos 给定的公共配置下对不同的 DataReader 对象进行分组。

属于同一订阅者的 DataReader 对象在订阅者之外没有任何其他关系,并且在其他SubscriberQos情况下独立运行。具体来说,订阅者可以托管不同主题和数据类型的 DataReader 对象。

服务质量

SubscriberQos控制Subscriber的行为。它在内部包含以下QosPolicy对象
在这里插入图片描述
QosPolicy有关它们的用法和默认值的更多信息,请参阅每个类的详细说明。

可以使用 Subscriber::set_qos()成员函数修改先前创建的订阅者的 QoS 值

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Subscriber with default SubscriberQos
Subscriber* subscriber =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
SubscriberQos qos = subscriber->get_qos();

// Modify QoS attributes
qos.entity_factory().autoenable_created_entities = false;

// Assign the new Qos to the object
subscriber->set_qos(qos);

默认订阅者Qos

默认的SubscriberQos是指DomainParticipant实例get_default_subscriber_qos()上的成员函数返回的值 。该特殊值可用作 QoS 参数 或 成员函数,以指示应使用当前默认的 SubscriberQos。SUBSCRIBER_QOS_DEFAULTcreate_subscriber()Subscriber::set_qos()

系统启动时,默认的 SubscriberQos 等价于默认的构造值SubscriberQos()。set_default_subscriber_qos()可以使用DomainParticipant 实例上的成员函数随时修改默认的 SubscriberQos 。修改默认的 SubscriberQos 不会影响已经存在的 Subscriber 实例。

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
SubscriberQos qos_type1 = participant->get_default_subscriber_qos();

// Modify QoS attributes
// (...)

// Set as the new default SubscriberQos
if (participant->set_default_subscriber_qos(qos_type1) != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

// Create a Subscriber with the new default SubscriberQos.
Subscriber* subscriber_with_qos_type1 =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber_with_qos_type1)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
SubscriberQos qos_type2;

// Modify QoS attributes
// (...)

// Set as the new default SubscriberQos
if (participant->set_default_subscriber_qos(qos_type2) != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

// Create a Subscriber with the new default SubscriberQos.
Subscriber* subscriber_with_qos_type2 =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber_with_qos_type2)
{
    // Error
    return;
}

// Resetting the default SubscriberQos to the original default constructed values
if (participant->set_default_subscriber_qos(SUBSCRIBER_QOS_DEFAULT)
        != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following
if (participant->set_default_subscriber_qos(SubscriberQos())
        != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

set_default_subscriber_qos()成员函数也接受特殊值SUBSCRIBER_QOS_DEFAULT作为输入参数。这会将当前默认的 SubscriberQos 重置为默认构造值SubscriberQos()。

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a custom SubscriberQos
SubscriberQos custom_qos;

// Modify QoS attributes
// (...)

// Create a subscriber with a custom SubscriberQos
Subscriber* subscriber = participant->create_subscriber(custom_qos);
if (nullptr == subscriber)
{
    // Error
    return;
}

// Set the QoS on the subscriber to the default
if (subscriber->set_qos(SUBSCRIBER_QOS_DEFAULT) != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following:
if (subscriber->set_qos(participant->get_default_subscriber_qos())
        != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

该值SUBSCRIBER_QOS_DEFAULT具有不同的含义,具体取决于它的使用位置:

create_subscriber()、Subscriber::set_qos()它指的是由 . 返回的默认 SubscriberQos get_default_subscriber_qos()。

set_default_subscriber_qos()它指的是默认构造 SubscriberQos()的.

订阅者监听器

SubscriberListener是一个抽象类,定义将响应 订阅者状态更改而触发的回调。默认情况下,所有这些回调都是空的并且什么都不做。用户应实现此类的特化,覆盖应用程序所需的回调。未被覆盖的回调将保持其空实现。

SubscriberListener 继承自DataReaderListener。因此,它能够对报告给 DataReader的所有事件做出反应。由于事件总是被通知给可以处理事件的最具体的实体侦听器,因此只有在触发的 DataReader 没有附加侦听器时,才会调用 SubscriberListener 从 DataReaderListener 继承的回调,或者如果回调被StatusMaskDataReader 上的 禁用。

此外,SubscriberListener 添加了以下回调:

on_data_on_readers(): 新数据在属于此订阅者的任何 DataReader 上可用。对此回调的调用没有排队,这意味着如果一次接收到多个新的数据更改,则可能只为所有这些调用发出一个回调调用,而不是每次更改一个。如果应用程序在此回调中检索接收到的数据,它必须继续 读取数据,直到没有留下新的更改。

class CustomSubscriberListener : public SubscriberListener
{

public:

    CustomSubscriberListener()
        : SubscriberListener()
    {
    }

    virtual ~CustomSubscriberListener()
    {
    }

    virtual void on_data_on_readers(
            Subscriber* sub)
    {
        (void)sub;
        std::cout << "New data available" << std::endl;
    }

};

创建订阅者

订阅者始终属于DomainParticipant 。订阅者的创建是通过create_subscriber()DomainParticipant 实例上的成员函数完成的,该实例充当订阅者的工厂。

强制性论点是:

描述订阅者行为的订阅者Qos 。如果提供SUBSCRIBER_QOS_DEFAULT的值为 ,则使用Default SubscriberQos的值。

可选参数是:

派生自SubscriberListener的侦听器,实现将触发的回调,以响应订阅者上的事件和状态更改。默认情况下使用空回调。

StatusMask激活或停用在 SubscriberListener 上触发单个回调的A。默认情况下,所有事件都已启用。

create_subscriber()如果在操作过程中出现错误,将返回一个空指针,例如,如果提供的 QoS 不兼容或不受支持。建议检查返回值是否为有效指针。

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Subscriber with default SubscriberQos and no Listener
// The value SUBSCRIBER_QOS_DEFAULT is used to denote the default QoS.
Subscriber* subscriber_with_default_qos =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber_with_default_qos)
{
    // Error
    return;
}

// A custom SubscriberQos can be provided to the creation method
SubscriberQos custom_qos;

// Modify QoS attributes
// (...)

Subscriber* subscriber_with_custom_qos =
        participant->create_subscriber(custom_qos);
if (nullptr == subscriber_with_custom_qos)
{
    // Error
    return;
}

// Create a Subscriber with default QoS and a custom Listener.
// CustomSubscriberListener inherits from SubscriberListener.
// The value SUBSCRIBER_QOS_DEFAULT is used to denote the default QoS.
CustomSubscriberListener custom_listener;
Subscriber* subscriber_with_default_qos_and_custom_listener =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT, &custom_listener);
if (nullptr == subscriber_with_default_qos_and_custom_listener)
{
    // Error
    return;
}

基于配置文件的订阅者创建

除了使用 SubscriberQos,配置文件的名称可用于创建具有create_subscriber_with_profile() DomainParticipant 实例上的成员函数的订阅者。

强制性论点是:

具有标识订阅者的名称的字符串。

可选参数是:

从 SubscriberListener 派生的侦听器,实现将触发的回调,以响应订阅者上的事件和状态更改。默认情况下使用空回调。

StatusMask激活或停用在 SubscriberListener 上触发单个回调的A。默认情况下,所有事件都已启用。

create_subscriber_with_profile()如果在操作过程中出现错误,将返回一个空指针,例如,如果提供的 QoS 不兼容或不受支持。建议检查返回值是否为有效指针。

XML 配置文件必须先前已加载。请参阅从 XML 文件加载配置文件。

// First load the XML with the profiles
DomainParticipantFactory::get_instance()->load_XML_profiles_file("profiles.xml");

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Subscriber using a profile and no Listener
Subscriber* subscriber_with_profile =
        participant->create_subscriber_with_profile("subscriber_profile");
if (nullptr == subscriber_with_profile)
{
    // Error
    return;
}

// Create a Subscriber using a profile and a custom Listener.
// CustomSubscriberListener inherits from SubscriberListener.
CustomSubscriberListener custom_listener;
Subscriber* subscriber_with_profile_and_custom_listener =
        participant->create_subscriber_with_profile("subscriber_profile", &custom_listener);
if (nullptr == subscriber_with_profile_and_custom_listener)
{
    // Error
    return;
}

删除订阅者

可以使用delete_subscriber()创建订阅者的 DomainParticipant 实例上的成员函数删除订阅者。

只有属于订阅者的所有实体 (DataReaders) 都已被删除,才能删除订阅者。否则,该函数将发出错误并且订阅者不会被删除。这可以通过使用Subscriberdelete_contained_entities()的成员函数 来执行。

// Create a DomainParticipant in the desired domain
DomainParticipant* participant =
        DomainParticipantFactory::get_instance()->create_participant(0, PARTICIPANT_QOS_DEFAULT);
if (nullptr == participant)
{
    // Error
    return;
}

// Create a Subscriber
Subscriber* subscriber =
        participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber)
{
    // Error
    return;
}

// Use the Subscriber to communicate
// (...)

// Delete the entities the subscriber created
if (subscriber->delete_contained_entities() != ReturnCode_t::RETCODE_OK)
{
    // Subscriber failed to delete the entities it created
    return;
}

// Delete the Subscriber
if (participant->delete_subscriber(subscriber) != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

数据读取器

ADataReader恰好连接到一个 充当它的工厂的订阅者。此外,每个 DataReader自创建以来都绑定到一个 主题。该主题必须在创建 DataReader 之前存在,并且必须绑定到 DataReader 要发布的数据类型。

在订阅者中为特定主题创建新的 DataReader 的效果是使用主题描述的名称和数据类型启动新订阅。

创建 DataReader 后,将在从远程发布接收到数据值的更改时通知应用程序。然后可以使用 DataReader 的DataReader::read_next_sample()或DataReader::take_next_sample() 成员函数检索这些更改

// Create a DataReader with default DataReaderQos
DataReader* data_reader =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
DataReaderQos qos = data_reader->get_qos();

// Modify QoS attributes
// (...)

// Assign the new Qos to the object
data_reader->set_qos(qos);

默认 DataReaderQos

默认的 DataReaderQos 是指订阅者实例get_default_datareader_qos()上的成员函数 返回的值 。该特殊值可用作 QoS 参数 或 成员函数,以指示应使用当前默认 DataReaderQos。DATAREADER_QOS_DEFAULTcreate_datareader()DataReader::set_qos()

系统启动时,默认的 DataReaderQos 等价于默认的构造值DataReaderQos()。可以随时使用 set_default_datareader_qos()订阅服务器实例上的成员函数修改默认 DataReaderQos。修改默认 DataReaderQos 不会影响已经存在的 DataReader实例。

// Get the current QoS or create a new one from scratch
DataReaderQos qos_type1 = subscriber->get_default_datareader_qos();

// Modify QoS attributes
// (...)

// Set as the new default DataReaderQos
if (subscriber->set_default_datareader_qos(qos_type1) != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

// Create a DataReader with the new default DataReaderQos.
DataReader* data_reader_with_qos_type1 =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader_with_qos_type1)
{
    // Error
    return;
}

// Get the current QoS or create a new one from scratch
DataReaderQos qos_type2;

// Modify QoS attributes
// (...)

// Set as the new default DataReaderQos
if (subscriber->set_default_datareader_qos(qos_type2) != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

// Create a DataReader with the new default DataReaderQos.
DataReader* data_reader_with_qos_type2 =
        subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader_with_qos_type2)
{
    // Error
    return;
}

// Resetting the default DataReaderQos to the original default constructed values
if (subscriber->set_default_datareader_qos(DATAREADER_QOS_DEFAULT)
        != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following
if (subscriber->set_default_datareader_qos(DataReaderQos())
        != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

set_default_datareader_qos()成员函数也接受特殊值DATAREADER_QOS_DEFAULT作为输入参数。这会将当前默认 DataReaderQos 重置为默认构造值DataReaderQos()。

// Create a custom DataReaderQos
DataReaderQos custom_qos;

// Modify QoS attributes
// (...)

// Create a DataWriter with a custom DataReaderQos
DataReader* data_reader = subscriber->create_datareader(topic, custom_qos);
if (nullptr == data_reader)
{
    // Error
    return;
}

// Set the QoS on the DataWriter to the default
if (data_reader->set_qos(DATAREADER_QOS_DEFAULT) != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

// The previous instruction is equivalent to the following:
if (data_reader->set_qos(subscriber->get_default_datareader_qos())
        != ReturnCode_t::RETCODE_OK)
{
    // Error
    return;
}

该值DATAREADER_QOS_DEFAULT具有不同的含义,具体取决于它的使用位置:

create_datareader() 、DataReader::set_qos()它指的是由返回的默认 DataReaderQos get_default_datareader_qos()。

set_default_datareader_qos()它指的是默认构造DataReaderQos()的

数据读取器监听器

DataReaderListener是一个抽象类,定义将响应DataReader上的状态更改而触发的回调。默认情况下,所有这些回调都是空的并且什么都不做。用户应实现此类的特化,覆盖应用程序所需的回调。未被覆盖的回调将保持其空实现。

DataReaderListener 定义了以下回调:

on_data_available():DataReader 上有可供应用程序使用的新数据。对此回调的调用没有排队,这意味着如果一次接收到多个新的数据更改,则可能只为所有这些调用发出一个回调调用,而不是每次更改一个。如果应用程序在此回调中检索接收到的数据,它必须继续 读取数据,直到没有留下新的更改。

on_subscription_matched(): DataReader 找到了 与Topic匹配且具有公共分区和兼容 QoS 的DataWriter,或者已停止与之前认为匹配的 DataWriter 匹配。当匹配的 DataWriter 更改其 DataWriterQos时也会触发它。

on_requested_deadline_missed(): DataReader 未在其DataReaderQos上配置的截止期限内接收数据。它将为 DataReader 丢失数据的每个截止期限和数据实例调用。
目前 on_requested_deadline_missed() 没有实现(永远不会被调用),将在 Fast DDS 的未来版本中实现。

on_requested_incompatible_qos(): DataReader 找到了一个与 Topic 匹配并具有公共分区的 DataWriter,但其 QoS 与 DataReader 上定义的 QoS 不兼容。

on_liveliness_changed():匹配的DataWriter的活跃度状态发生了变化。不活动的 DataWriter已变为活动状态或相反。

on_sample_rejected():接收到的数据样本被拒绝。有关详细信息,请参阅SampleRejectedStatus。

on_sample_lost():数据样本丢失,永远不会被接收。有关详细信息,请参阅SampleLostStatus。

class CustomDataReaderListener : public DataReaderListener
{

public:

    CustomDataReaderListener()
        : DataReaderListener()
    {
    }

    virtual ~CustomDataReaderListener()
    {
    }

    virtual void on_data_available(
            DataReader* reader)
    {
        (void)reader;
        std::cout << "Received new data message" << std::endl;
    }

    virtual void on_subscription_matched(
            DataReader* reader,
            const SubscriptionMatchedStatus& info)
    {
        (void)reader;
        if (info.current_count_change == 1)
        {
            std::cout << "Matched a remote DataWriter" << std::endl;
        }
        else if (info.current_count_change == -1)
        {
            std::cout << "Unmatched a remote DataWriter" << std::endl;
        }
    }

    virtual void on_requested_deadline_missed(
            DataReader* reader,
            const eprosima::fastrtps::RequestedDeadlineMissedStatus& info)
    {
        (void)reader, (void)info;
        std::cout << "Some data was not received on time" << std::endl;
    }

    virtual void on_liveliness_changed(
            DataReader* reader,
            const eprosima::fastrtps::LivelinessChangedStatus& info)
    {
        (void)reader;
        if (info.alive_count_change == 1)
        {
            std::cout << "A matched DataWriter has become active" << std::endl;
        }
        else if (info.not_alive_count_change == 1)
        {
            std::cout << "A matched DataWriter has become inactive" << std::endl;
        }
    }

    virtual void on_sample_rejected(
            DataReader* reader,
            const eprosima::fastrtps::SampleRejectedStatus& info)
    {
        (void)reader, (void)info;
        std::cout << "A received data sample was rejected" << std::endl;
    }

    virtual void on_requested_incompatible_qos(
            DataReader* /*reader*/,
            const RequestedIncompatibleQosStatus& info)
    {
        std::cout << "Found a remote Topic with incompatible QoS (QoS ID: " << info.last_policy_id <<
            ")" << std::endl;
    }

    virtual void on_sample_lost(
            DataReader* reader,
            const SampleLostStatus& info)
    {
        (void)reader, (void)info;
        std::cout << "A data sample was lost and will not be received" << std::endl;
    }

};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值