15.15. Remote Type Discovery and Endpoint Matching
本节解释了如何使用先前未知的远程发现数据类型在运行时创建端点。
15.15.1. Prerequisites
此用例专注于如何在运行时使用远程端点发现信息创建一个未知主题的端点。因此,先决条件为:
- 两个参与者A和B在不同进程中运行(类型信息在同一DomainParticipantFactory中共享)。
- 参与者A必须不知道参与者B注册的数据类型。
- 参与者B的数据类型必须使用eProsima Fast DDS-Gen生成的代码进行注册,并且没有禁用TypeObjectSupport代码生成。
- 参与者B必须使用参与者A未知的数据类型创建一个端点。
- 参与者A必须附加到DomainParticipantListener。
15.15.2. Remote Type Discovery
在参与者发现阶段之后,交换了端点信息。根据远程参与者创建的端点类型,调用适当的on_data_reader_discovery()
或on_data_writer_discovery()
回调。端点发现回调提供对远程发现信息的访问,包括TypeInformation。
通过提供的TypeInformation,可以查询ITypeObjectRegistry单例以获取相应的TypeObject表示,调用ITypeObjectRegistry::get_type_object
API。
15.15.3. Register Remote Type
DynamicTypeBuilderFactory
提供了一个特定API,该API根据给定的TypeObject表示返回相应的DynamicTypeBuilder:DynamicTypeBuilderFactory::create_type_w_type_object
。然后可以获得DynamicType并使用DynamicPubSubType进行注册。
15.15.4. Create Local Endpoint
一旦远程类型被本地注册,就可以在DomainParticipant中创建Topic,并且可以使用该Topic也创建端点。
注意: 端点匹配会考虑QoS一致性。因此,为了使本地端点匹配,还需考虑远程QoS。通过发现回调提供的远程端点发现信息也包括这些数据。
15.15.5. Example
以下代码片段展示了上述步骤:
class RemoteDiscoveryDomainParticipantListener : public DomainParticipantListener
{
/* 自定义回调 on_data_reader_discovery */
void on_data_reader_discovery(
DomainParticipant* participant,
eprosima::fastdds::rtps::ReaderDiscoveryStatus reason,
const eprosima::fastdds::rtps::SubscriptionBuiltinTopicData& info,
bool& should_be_ignored) override
{
should_be_ignored = false;
// 获取远程类型信息
xtypes::TypeObject remote_type_object;
if (RETCODE_OK != DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
info.type_information.type_information.complete().typeid_with_size().type_id(),
remote_type_object))
{
// 错误处理
return;
}
// 注册远程发现类型
DynamicType::_ref_type remote_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_type_object(
remote_type_object)->build();
TypeSupport dyn_type_support(new DynamicPubSubType(remote_type));
dyn_type_support.register_type(participant);
// 使用远程发现的类型创建主题。
Topic* topic =
participant->create_topic(info.topic_name.to_string(), dyn_type_support.get_type_name(),
TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
// 错误处理
return;
}
// 创建发布者和数据写入器
Publisher* publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);
if (nullptr == publisher)
{
// 错误处理
return;
}
DataWriter* data_writer = publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
if (nullptr == data_writer)
{
// 错误处理
return;
}
}
/* 自定义回调 on_data_writer_discovery */
void on_data_writer_discovery(
DomainParticipant* participant,
eprosima::fastdds::rtps::WriterDiscoveryStatus reason,
const eprosima::fastdds::dds::PublicationBuiltinTopicData& info,
bool& should_be_ignored) override
{
should_be_ignored = false;
// 获取远程类型信息
xtypes::TypeObject remote_type_object;
if (RETCODE_OK != DomainParticipantFactory::get_instance()->type_object_registry().get_type_object(
info.type_information.type_information.complete().typeid_with_size().type_id(),
remote_type_object))
{
// 错误处理
return;
}
// 注册远程发现类型
DynamicType::_ref_type remote_type = DynamicTypeBuilderFactory::get_instance()->create_type_w_TYPE_OBJECT(
remote type object)->build();
TypeSupport dyn_typenate(新动态pubsub type(remote type));
dyn_typesupport.register_types(participant);
// 创建一个具有所发现功能的新话题。
Topic * topic =
participant->create_topic(info.topic_name.to_string(), dyn_time_get.type_name(),
TOPIC_QOS_DEFAULT);
if (nullptr== topic)
{
– error handling
return;
}
Subscriber * subscriber=participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr==subscriber)
{
– error handling
return;
}
数据读取器 * 数据读取器=订阅者-> create_datareader(topic, DATAREADER_QOS_DEFAULT);
如果(nullptr==data_reader)
{
– error handling
返回;
}
}
};
这个示例展示了如何在接收到远程发件人的消息时动态地探测、注册新的数据类型并创建相关主题与通信实体。这种方法允许系统在没有预先知识情况下灵活扩展其能力。
内容由零声教学AI助手提供,问题来源于学员提问