15.15. Remote type discovery and endpoint matching
This section explains how to create an endpoint using a remotely discovered data type that was previously unknown to the local participant.
15.15.1. Prerequisites
This use case focuses on the strategy to follow in order to create an endpoint at runtime in a previously unknown topic using the information provided by the remote endpoint discovery information. Therefore, the prerequisites are:
Two participants, A and B, running in different process (type information is shared within the same DomainParticipantFactory).
Participant A must not know the data type registered in participant B.
Participant B data type must be registered using the code generated by eProsima Fast DDS-Gen without disabling the TypeObjectSupport code generation.
Participant B must create an endpoint using the data type unknown by participant A.
Participant A must be attached to a DomainParticipantListener.
15.15.2. Remote type discovery
Following the participant discovery phase, the endpoint information is exchanged.
The appropriate on_data_reader_discovery()
or
on_data_writer_discovery()
callback is called, depending on the kind of endpoint
created on the remote participant.
The endpoint discovery callback provides access to the remotely discovered information including the TypeInformation.
Provided the TypeInformation
, ITypeObjectRegistry
singleton can be queried for the corresponding
TypeObject representation calling ITypeObjectRegistry::get_type_object
API.
15.15.3. Register remote type
DynamicTypeBuilderFactory
provides a specific API that given a TypeObject representation returns the corresponding
DynamicTypeBuilder
: DynamicTypeBuilderFactory::create_type_w_type_object
.
The DynamicType
can then be obtained and registered using DynamicPubSubType
.
15.15.4. Create local endpoint
Once the remote type has been locally registered, a Topic can be created within the DomainParticipant and endpoints using this Topic might be also created.
Note
Endpoint matching takes into consideration QoS consistency. Consequently, for the local endpoint to match, the remote QoS has to be taken into account. The remote endpoint discovery information provided by the discovery callback includes also this data.
15.15.5. Example
The following snippet shows the previously explained steps:
class RemoteDiscoveryDomainParticipantListener : public DomainParticipantListener
{
/* Custom Callback 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;
// Get remote type information
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))
{
// Error
return;
}
// Register remotely discovered type
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);
// Create a Topic with the remotely discovered type.
Topic* topic =
participant->create_topic(info.topic_name.to_string(), dyn_type_support.get_type_name(),
TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
// Error
return;
}
// Create endpoint
Publisher* publisher = participant->create_publisher(PUBLISHER_QOS_DEFAULT);
if (nullptr == publisher)
{
// Error
return;
}
DataWriter* data_writer = publisher->create_datawriter(topic, DATAWRITER_QOS_DEFAULT);
if (nullptr == data_writer)
{
// Error
return;
}
}
/* Custom Callback 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;
// Get remote type information
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))
{
// Error
return;
}
// Register remotely discovered type
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);
// Create a Topic with the remotely discovered type.
Topic* topic =
participant->create_topic(info.topic_name.to_string(), dyn_type_support.get_type_name(),
TOPIC_QOS_DEFAULT);
if (nullptr == topic)
{
// Error
return;
}
// Create endpoint
Subscriber* subscriber = participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT);
if (nullptr == subscriber)
{
// Error
return;
}
// The QoS depends on the remote endpoint QoS. For simplicity, default QoS have been assumed.
DataReader* data_reader = subscriber->create_datareader(topic, DATAREADER_QOS_DEFAULT);
if (nullptr == data_reader)
{
// Error
return;
}
}
};