发现协议定义了给定Topic下publisher的DataWriter和subscriber的DataReader的匹配机制,以便它们之间共享数据,服务发现出现在服务通信过程中的任何时刻。
发现阶段
参与者发现阶段(Participant Discovery Phase PDP)
域名参与者互相发现,每个DomainParticipant定期发送公告消息,指定DomainParticipator正在侦听传入元数据和用户数据流量的单播地址(IP和端口),当两个给定的DomainParticipants存在于同一DDS域中时,它们将匹配。
端点发现阶段(Endpoint Discovery Phase EDP)
数据写入器和数据读取器相互确认,DomainParticipants使用PDP期间建立的通信信道,相互共享有关其DataWriter和DataReader的信息。这些信息包括主题和数据类型(请参阅主题)。要使两个端点匹配,它们的主题和数据类型必须一致。一旦DataWriter和DataReader匹配,它们就可以发送/接收用户数据流量了。
PDP的时候会创建一对Writer和Reader,PDP的过程是无状态的不需要去响应。
EDP创建的时候需要创建两对,第一对Publisher:Writer&Reader 第二对Subscriber:Writer&Reader两对进行匹配,也就是两个Paticipant之间的Topic和QoS匹配。
发现机制
- 简单发现(SimpleDiscovery)
默认机制。它支持PDP和EDP的RTPS标准,因此提供了与任何其他DDS和RTPS实现的兼容性。DomainParticipant在初始阶段单独被发现,以便在后面匹配它们下面的DataWriter和DataReader - 静态发现(StaticDiscovery)
这种机制实现了DomainParticipant之间的发现,在PDP阶段使用简单参与者发现协议(SPDP)(如RTPS标准所规定的),但当所有DataWriters和DataReaders的IP和端口、数据类型和Topics事先已知时,允许跳过简单端点发现协议(SEDP)阶段。 - 发现服务器(DiscoveryServer)
使用集中式发现体系结构,其中DomainParticipant(称为服务器)充当元流量发现的中心。 - 手动发现(ManualDiscovery)
该机制仅与RTPS层兼容。它禁用PDP,允许用户使用其选择的任何外部元信息信道手动匹配和取消匹配RTPS参与者、RTPSReader和RTPSWriter。因此,用户必须访问DomainParticipant实现的RTPSParticipant,并直接匹配RTPS实体。
发现协议的配置:
DomainParticipantQos pqos;
pqos.wire_protocol().builtin.discovery_config.discoveryProtocol =
DiscoveryProtocol_t::SIMPLE;
如果需要使用静态发现协议,则必须禁用SEDP,如下:
DomainParticipantQos pqos;
pqos.wire_protocol().builtin.discovery_config.use_SIMPLE_EndpointDiscoveryProtocol = false;
pqos.wire_protocol().builtin.discovery_config.use_STATIC_EndpointDiscoveryProtocol = true;
xml配置配置文件
fastdds提供了通过xml文件配置一些设置,因此用户可以通过配置修改fastdds实体的行为,而无需通过源代码的接口实现,也不用重新编译源代码。
用户拥有每个API的功能标签,可以通过标签配置DomainParticipant的行为,通过、标签配置DataWriter、DataReader等的行为。
发现流程源码剖析
- 创建Participant时,会初始化RTPSParticipantImpl,此时会根据配置的组播或者单播ip:port创建一个接收线程,这个线程会不断接收消息,并将DataReader注册到线程里;另外会初始化内置的协议,用来做服务发现
RTPSParticipantImpl::RTPSParticipantImpl(
uint32_t domain_id,
const RTPSParticipantAttributes& PParam,
const GuidPrefix_t& guidP,
const GuidPrefix_t& persistence_guid,
RTPSParticipant* par,
RTPSParticipantListener* plisten)
: domain_id_(domain_id)
, m_att(PParam)
, m_guid(guidP, c_EntityId_RTPSParticipant)
, mp_builtinProtocols(nullptr)
, mp_ResourceSemaphore(new Semaphore(0))
, IdCounter(0)
, type_check_fn_(nullptr)
, client_override_(false)
, internal_metatraffic_locators_(false)
, internal_default_locators_(false</