8.5 发现模块
RTPS 行为模块假设 RTPS 端点已正确配置并与匹配的远程端点配对。它不对这种配置是如何发生的做任何假设,只定义了如何在这些端点之间交换数据。
为了能够配置端点,实现必须获得有关远程端点及其属性的存在的信息。如何获得此信息是发现模块的主题。
发现模块定义了 RTPS 发现协议。发现协议的目的是让每个 RTPS 参与者发现其他相关参与者及其端点。一旦发现了远程端点,实现可以相应地配置本地端点以建立通信。
DDS 规范同样依赖于使用发现机制在匹配的 DataWriters 和 DataReaders 之间建立通信。DDS 实现必须自动发现网络中加入和离开的远程实体的存在。这些发现信息通过 DDS 内置主题提供给用户。
此模块中定义的 RTPS 发现协议为 DDS 提供了所需的发现机制。
8.5.1 概述
RTPS 规范将发现协议分为两个独立的协议:
-
参与者发现协议
-
端点发现协议
参与者发现协议(PDP)指定参与者如何在网络中相互发现。一旦两个参与者发现了彼此,他们就会使用端点发现协议(EDP)交换它们包含的端点信息。除了这种因果关系外,这两个协议可以被认为是独立的。 实现可能选择支持多个 PDP 和 EDP,可能是特定于供应商的。只要两个参与者至少有一个 PDP 和 EDP 共同,他们就可以交换所需的发现信息。 为了互操作性,所有 RTPS 实现都必须提供至少以下发现协议:
-
简单参与者发现协议(SPDP)
-
简单端点发现协议(SEDP)
这两个都是基本的发现协议,足以满足中小规模网络的需要。针对更大网络的额外 PDP 和 EDP 可能会添加到规范的未来版本中。 最后,发现协议的作用是提供有关发现的远程端点的信息。参与者如何使用这些信息来配置其本地端点取决于 RTPS 协议的实际实现,并不是发现协议规范的一部分。例如,对于在 8.4.7 中介绍的参考实现,获得的远程端点信息允许实现配置: • 与每个 RTPS StatelessWriter 关联的 RTPS ReaderLocator 对象。 • 与每个 RTPS StatefulWriter 关联的 RTPS ReaderProxy 对象。 • 与每个 RTPS StatefulReader 关联的 RTPS WriterProxy 对象。 发现模块的组织如下: • SPDP 和 SEDP 依赖于预定义的 RTPS 内置写入器和读取器端点来交换发现信息。8.5.2 引入了这些 RTPS 内置端点。 • 8.5.3 讨论了 SPDP。 • 8.5.4 讨论了 SEDP。
8.5.2 RTPS 内置发现端点
DDS 规范规定,使用预定义的主题和 QoS 的“内置”DDS DataReaders 和 DataWriters 进行发现。 有四个预定义的内置主题:“DCPSParticipant”,“DCPSSubscription”,“DCPSPublication”和“DCPSTopic”。DDS 规范还指定了与这些主题关联的 DataTypes,主要包含实体 QoS 值。对于每个内置主题,都存在一个相应的 DDS 内置 DataWriter 和 DDS 内置 DataReader。内置 DataWriters 用于向网络的其余部分宣布本地 DDS 参与者及其包含的 DDS 实体(DataReaders、DataWriters 和主题)的存在和 QoS。同样,内置 DataReaders 从远程参与者那里收集这些信息,然后由 DDS 实现用于识别匹配的远程实体。内置 DataReaders 充当常规 DDS DataReaders,并且用户也可以通过 DDS API 访问它们。 RTPS 简单发现协议(SPDP 和 SEDP)采用的方法类似于内置实体概念。RTPS 将每个内置的 DDS DataWriter 或 DataReader 映射到关联的内置 RTPS 端点。这些内置端点充当常规的写入器和读取器端点,并提供使用常规 RTPS 协议在参与者之间交换所需发现信息的手段,该协议在行为模块中定义。 SPDP,它关注参与者如何相互发现,映射了“DCPSParticipant”主题的 DDS 内置实体。SEDP,它指定如何交换有关本地主题、DataWriters 和 DataReaders 的发现信息,映射了“DCPSSubscription”,“DCPSPublication”和“DCPSTopic”主题的 DDS 内置实体。
8.5.3 简单参与者发现协议
PDP 的目的是在网络中发现其他参与者的存在及其属性。 参与者可能支持多个 PDP,但为了互操作性,所有实现都必须至少支持简单参与者发现协议。
8.5.3.1 一般方法
RTPS 简单参与者发现协议(SPDP)采用一种简单的方法来宣布和检测域中参与者的存在。 对于每个参与者,SPDP 创建两个 RTPS 内置端点:SPDPbuiltinParticipantWriter 和 SPDPbuiltinParticipantReader。 SPDPbuiltinParticipantWriter 是一个 RTPS 最佳努力无状态写入器。SPDPbuiltinParticipantWriter 的 HistoryCache 包含一个类型为 SPDPdiscoveredParticipantData 的单个数据对象。此数据对象的值从参与者中的属性设置。如果属性更改,数据对象将被替换。 SPDPbuiltinParticipantWriter 定期将此数据对象发送到预配置的定位器列表,以宣布参与者在网络上的存在。这是通过定期调用 StatelessWriter::unsent_changes_reset 实现的,这会导致 StatelessWriter 将其 HistoryCache 中存在的所有更改重新发送到所有定位器。SPDPbuiltinParticipantWriter 发送 SPDPdiscoveredParticipantData 的周期率默认为 PSM 指定的值。此周期应小于 SPDPdiscoveredParticipantData 中指定的 leaseDuration(另见 8.5.3.3.2)。 预配置的定位器列表可能包括单播和多播定位器。端口号由每个 PSM 定义。这些定位器仅代表网络中可能的远程参与者,实际上不需要有参与者存在。通过定期发送 SPDPdiscoveredParticipantData,参与者可以按任何顺序加入网络。 SPDPbuiltinParticipantReader 接收来自远程参与者的 SPDPdiscoveredParticipantData 公告。包含的信息包括远程参与者支持的端点发现协议。然后使用适当的端点发现协议与远程参与者交换端点信息。 实现可以通过在收到来自先前未知参与者的此数据对象后发送额外的 SPDPdiscoveredParticipantData 来最小化任何启动延迟,但此行为是可选的。 实现还可以使用户选择是否自动将预配置的定位器列表扩展到新发现的参与者的新定位器。这使得定位器列表不对称。这最后两个功能是可选的,不是互操作性的要求。
8.5.3.2 SPDPdiscoveredParticipantData
SPDPdiscoveredParticipantData 定义了作为 SPDP 的一部分交换的数据。 图 8.27 展示了 SPDPdiscoveredParticipantData 的内容。如图所示,SPDPdiscoveredParticipantData 专门化了 ParticipantProxy,因此包括配置发现参与者所需的所有信息。SPDPdiscoveredParticipantData 还专门化了 DDS 定义的 DDS::ParticipantBuiltinTopicData,提供了相应的 DDS 内置 DataReader 需要的信息。
图 8.27 - SPDPdiscoveredParticipantData
SPDPdiscoveredParticipantData 的属性及其解释在表 8.73 中描述。
表 8.73 - RTPS SPDPdiscoveredParticipantData 属性
RTPS SPDPdiscoveredParticipantData | ||
属性名称 | 属性类型 | 含义 |
domainId | DomainId_t | 标识与之关联的 DDS DomainParticipant 的 DDS domainId。 |
domainTag | string | 标识与之关联的 DDS DomainParticipant 的 DDS domainTag。 |
protocolVersion | ProtocolVersion_t | 标识参与者使用的 RTPS 协议版本。 |
guidPrefix | GuidPrefix_t | 参与者及其包含的所有端点的通用 GuidPrefix_t。 |
vendorId | VendorId_t | 标识包含参与者的 DDS 中间件的供应商。 |
expectsInlineQos | bool | 描述参与者内的读者是否期望每个数据修改适用的 QoS 值与每个数据一起封装。 |
metatrafficUnicastLocatorList | Locator_t[*] | 可用于向参与者中包含的内置端点发送消息的单播定位器(传输、地址、端口组合)列表。 |
metatrafficMulticastLocatorList | Locator_t[*] | 可用于向参与者中包含的内置端点发送消息的多播定位器(传输、地址、端口组合)列表。 |
defaultUnicastLocatorList | Locator_t[1..*] | 可用于向参与者中包含的用户定义端点发送消息的默认单播定位器(传输、地址、端口组合)列表。这些是在端点未指定自己的定位器集合时将使用的单播定位器,因此至少必须存在一个定位器。 |
defaultMulticastLocatorList | Locator_t[*] | 可用于向参与者中包含的用户定义端点发送消息的默认多播定位器(传输、地址、端口组合)列表。这些是在端点未指定自己的定位器集合时将使用的多播定位器。 |
availableBuiltinEndpoints | BuiltinEndpointSet_t | 所有参与者必须支持 SEDP。此属性标识参与者中可用的内置 SEDP 端点类型。这使参与者能够指出它只包含可能内置端点的一个子集。另见 8.5.4.3。BuiltinEndpointSet_t 中可能的成员包括:PUBLICATIONS_DETECTOR, PUBLICATIONS_ANNOUNCER, SUBSCRIPTIONS_DETECTOR, SUBSCRIPTIONS_ANNOUNCER, TOPICS_DETECTOR, TOPICS_ANNOUNCER, PARTICIPANT_MESSAGE_READER, PARTICIPANT_MESSAGE_WRITER。供应商特定的扩展可以用来表示对额外 EDP 的支持。 |
leaseDuration | Duration_t | 每次从参与者接收到公告时,应考虑参与者活跃的时间长短。如果参与者在此时间段内未发送另一个公告,则可以认为参与者已经离开。在这种情况下,可以释放与参与者及其端点相关的任何资源。 |
manualLivelinessCount | Count_t | 用于实现 MANUAL_BY_PARTICIPANT 生存期 QoS。当生存期被断言时,manualLivelinessCount 递增,并发送新的 SPDPdiscoveredParticipantData。 |
builtinEndpointQos | BuiltinEndpointQos_t | 提供有关参与者支持的内置端点 QoS 的附加信息。 |
正如 8.5.3.1 中提到的,SPDPdiscoveredParticipantData 列出了参与者支持的端点发现协议(Endpoint Discovery Protocols)。表 8.73 中显示的属性仅反映了强制性的 SEDP。目前 RTPS 规范没有定义其他的端点发现协议。为了扩展 SPDPdiscoveredParticipantData 以包括额外的 EDP,可以使用标准的 RTPS 扩展机制。有关额外信息,请参见 9.6.2。
8.5.3.3 简单参与者发现协议所使用的内置端点
图 8.28 展示了简单参与者发现协议引入的内置端点。
图 8.28 - 简单参与者发现协议使用的内置端点
该协议为 SPDP 内置端点保留了以下 EntityId_t 的值:
ENTITYID_SPDP_BUILTIN_PARTICIPANT_WRITER
ENTITYID_SPDP_BUILTIN_PARTICIPANT_READER
8.5.3.3.1 SPDPbuiltinParticipantWriter
配置 SPDPbuiltinParticipantWriter 的相关属性值显示在表 8.74 中。
表 8.74 - SPDP 使用的 RTPS 无状态写入器的属性
SPDPbuiltinParticipantWriter | ||
属性名称 | 属性类型 | 值 |
unicastLocatorList | Locator_t[*] | <自动检测> 传输类型和地址要么是自动检测的,要么由应用程序配置。端口是 SPDP 初始化的一个参数,或者设置为取决于 domainId 的 PSM 指定的值。 |
multicastLocatorList | Locator_t[*] | <SPDP 初始化的参数> 默认为 PSM 指定的值。 |
reliabilityLevel | ReliabilityKind_t | BEST_EFFORT |
topicKind | TopicKind_t | WITH_KEY |
resendPeriod | Duration_t | <SPDP 初始化的参数> 默认为 PSM 指定的值。 |
readerLocators | ReaderLocator[*] | <SPDP 初始化的参数> |
8.5.3.3.2 SPDPbuiltinParticipantReader
SPDPbuiltinParticipantReader 配置了表 8.75 中显示的属性值。
表 8.75 - SPDP 使用的 RTPS 无状态读取器的属性
SPDPbuiltinParticipantReader | ||
属性名称 | 属性类型 | 值 |
unicastLocatorList | Locator_t[*] | <自动检测> 传输类型和地址要么是自动检测的,要么由应用程序配置。端口是 SPDP 初始化的一个参数,或者设置为取决于 domainId 的 PSM 指定的值。 |
multicastLocatorList | Locator_t[*] | <SPDP 初始化的参数> 默认为 PSM 指定的值。 |
reliabilityLevel | ReliabilityKind_t | BEST_EFFORT |
topicKind | TopicKind_t | WITH_KEY |
SPDPbuiltinParticipantReader 的 HistoryCache 包含有关所有活跃发现参与者的信息;用于识别每个数据对象的键对应于参与者的 GUID。
每次 SPDPbuiltinParticipantReader 收到关于某个参与者的信息时,SPDP 会检查 HistoryCache,寻找键与参与者 GUID 匹配的条目。如果没有找到匹配键的条目,将添加一个以参与者的 GUID 为键的新条目。
SPDP 定期检查 SPDPbuiltinParticipantReader 的 HistoryCache,寻找陈旧的条目,定义为那些在超过其指定的 leaseDuration 时间内未被刷新的条目。陈旧的条目将被移除。
8.5.3.4 简单参与者发现协议使用的逻辑端口
如上所述,每个 SPDPbuiltinParticipantWriter 使用预配置的定位器列表来宣布参与者在网络上的存在。
为了实现即插即用的互操作性,预配置的定位器列表必须使用以下众所周知的逻辑端口:
表 8.76 - 简单参与者发现协议使用的逻辑端口
端口 | 使用此端口配置的定位器 |
SPDP_WELL_KNOWN_UNICAST_PORT | SPDPbuiltinParticipantReader.unicastLocatorList 中的条目,SPDPbuiltinParticipantWriter.readerLocators 中的单播条目 |
SPDP_WELL_KNOWN_MULTICAST_PORT | SPDPbuiltinParticipantReader.multicastLocatorList 中的条目,SPDPbuiltinParticipantWriter.readerLocators 中的多播条目 |
逻辑端口的实际值由 PSM 定义。
8.5.4 简单端点发现协议
端点发现协议定义了两个参与者之间所需的信息交换,以便发现彼此的写入器和读取器端点。
一个参与者可能支持多个 EDP,但为了互操作性,所有实现都必须至少支持简单端点发现协议。
8.5.4.1 一般方法
与 SPDP 类似,简单端点发现协议使用预定义的内置端点。预定义内置端点的使用意味着,一旦一个参与者知道另一个参与者的存在,它就可以假定远程参与者提供的内置端点的存在,并与本地匹配的内置端点建立关联。
用于内置端点之间通信的协议与应用定义端点的协议相同。因此,通过阅读内置的读取器端点,协议虚拟机可以发现任何远程参与者所属的 DDS 实体的存在和 QoS。类似地,通过写入内置的写入器端点,参与者可以通知其他参与者本地 DDS 实体的存在和 QoS。
因此,SEDP 中内置主题的使用减少了整体发现协议的范围,仅限于确定系统中存在哪些参与者以及与这些参与者的内置端点相对应的 ReaderProxy 和 WriterProxy 对象的属性值。一旦知道这些,其他一切都是应用 RTPS 协议到内置 RTPS 读取器和写入器之间的通信的结果。
8.5.4.2 简单端点发现协议使用的内置端点
SEDP 映射了 DDS 内置实体“DCPSSubscription”,“DCPSPublication”和“DCPSTopic”主题。根据 DDS 规范,这些内置实体的可靠性 QoS 设置为“可靠”。因此,SEDP 将每个相应的内置 DDS DataWriter 或 DataReader 映射到相应的可靠 RTPS 写入器和读取器端点。
例如,如图 8.29 所示,“DCPSSubscription”,“DCPSPublication”和“DCPSTopic”主题的 DDS 内置 DataWriters 可以映射到可靠的 RTPS StatefulWriters,相应的 DDS 内置 DataReaders 映射到可靠的 RTPS StatefulReaders。实际实现不必使用有状态的参考实现。为了互操作性,只需实现提供所需的内置端点和可靠通信,满足 8.4.2 中列出的一般要求即可。
图 8.29 - DDS 内置实体到相应 RTPS 内置端点的示例映射
RTPS 协议为内置端点保留了以下 EntityId_t 的值:
ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER
ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR
ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER
ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR
ENTITYID_SEDP_BUILTIN_TOPICS_ANNOUNCER
ENTITYID_SEDP_BUILTIN_TOPICS_DETECTOR
保留的 EntityId_t 的实际值由每个 PSM 定义。
8.5.4.3 简单端点发现协议所需的内置端点
实现不需要提供所有内置端点。
如 DDS 规范中所述,主题传播是可选的。因此,不需要实现 SEDPbuiltinTopicsReader 和 SEDPbuiltinTopicsWriter 内置端点,为了互操作性,实现不应依赖于远程参与者中它们的存在。
至于其余的内置端点,参与者只需要提供用于匹配本地和远程端点的内置端点。例如,如果 DDS 参与者只包含 DDS DataWriters,唯一所需的 RTPS 内置端点是 SEDPbuiltinPublicationsWriter 和 SEDPbuiltinSubscriptionsReader。在这种情况下,SEDPbuiltinPublicationsReader 和 SEDPbuiltinSubscriptionsWriter 内置端点没有作用。
SPDP 指定参与者如何通知其他参与者它有哪些内置端点可用。这在 8.5.3.2 中进行了讨论。
8.5.4.4 简单端点发现协议使用的内置端点相关的数据类型
每个 RTPS 端点都有一个 HistoryCache,用于存储与端点关联的数据对象的更改。这也适用于 RTPS 内置端点。因此,每个 RTPS 内置端点都依赖于某种 DataType,代表写入其 HistoryCache 的数据的逻辑内容。
图 8.30 定义了与 RTPS 内置端点相关的 DiscoveredWriterData、DiscoveredReaderData 和 DiscoveredTopicData 数据类型,这些端点用于“DCPSPublication”,“DCPSSubscription”和“DCPSTopic”主题。与“DCPSParticipant”主题相关的 DataType 在 8.5.3.2 中定义。
与每个 RTPS 内置端点相关的 DataType 包含 DDS 为相应的内置 DDS 实体指定的所有信息。因此,DiscoveredReaderData 扩展了 DDS 定义的 DDS::SubscriptionBuiltinTopicData,DiscoveredWriterData 扩展了 DDS::PublicationBuiltinTopicData,而 DiscoveredTopicData 扩展了 DDS::TopicBuiltinTopicData。
除了与相关内置 DDS 实体所需的数据外,“Discovered”数据类型还包括协议实现可能需要的所有信息,以配置 RTPS 端点。这些信息包含在 RTPS ReaderProxy 和 WriterProxy 中。
图 8.30 - 与简单端点发现协议使用的内置端点相关联的数据类型
协议的实现不必一定发送 DataTypes 中包含的所有信息。如果任何信息不存在,实现可以假设 PSM 定义的默认值。PSM 还定义了发现信息在网络上的表示方式。
SEDP 使用的 RTPS 内置端点及其关联的数据类型如图 8.31 所示。
图 8.31 - 内置端点及其各自的 HistoryCache 关联的数据类型
每个内置端点的 HistoryCache 的内容可以根据以下方面来描述:数据类型(DataType)、基数(Cardinality)、数据对象插入、数据对象修改和数据对象删除。
-
数据类型(DataType)。存储在缓存中的数据的类型。这部分由 DDS 规范定义。
-
基数(Cardinality)。可以存储在缓存中的不同数据对象(每个具有不同键)的数量。
-
数据对象插入。插入新数据对象到缓存中的条件。
-
数据对象修改。修改现有数据对象的值的条件。
-
数据对象删除。从缓存中删除现有数据对象的条件。描述每个内置端点的 HistoryCache 是具有说明性的。
8.5.4.4.1 SEDPbuiltinPublicationsWriter 和 SEDPbuiltinPublicationsReader
表 8.77 描述了 SEDPbuiltinPublicationsWriter 和 SEDPbuiltinPublicationsReader 的 HistoryCache。
表 8.77 - SEDPbuiltinPublicationsWriter 和 SEDPbuiltinPublicationsReader 的 HistoryCache 内容
方面 | 描述 |
数据类型(DataType) | DiscoveredWriterData |
基数(Cardinality) | 由 DomainParticipant 包含的 DataWriter 的数量。参与者中的每个 DataWriter 与存储在 SEDPbuiltinPublicationsWriter 的 WriterHistoryCache 中描述 DataWriter 的数据对象之间存在一对一的对应关系。 |
数据对象插入(Data-Object insertion) | 每次在 DomainParticipant 中创建 DataWriter 时。 |
数据对象修改(Data-Object modification) | 每次修改现有 DataWriter 的 QoS 时。 |
数据对象删除(Data-Object deletion) | 每次删除属于 DomainParticipant 的现有 DataWriter 时。 |
8.5.4.4.2 SEDPbuiltinSubscriptionsWriter 和 SEDPbuiltinSubscriptionsReader
表 8.78 描述了 SEDPbuiltinSubscriptionsWriter 和 SEDPbuiltinSubscriptionsReader 的 HistoryCache。
表 8.78 - SEDPbuiltinSubscriptionsWriter 和 SEDPbuiltinSubscriptionsReader 的 HistoryCache 内容
方面 | 描述 |
数据类型(DataType) | DiscoveredReaderData |
基数(Cardinality) | 由 DomainParticipant 包含的 DataReader 的数量。参与者中的每个 DataReader 与存储在 SEDPbuiltinSubscriptionsWriter 的 WriterHistoryCache 中描述 DataReader 的数据对象之间存在一对一的对应关系。 |
数据对象插入(Data-Object insertion) | 每次在 DomainParticipant 中创建 DataReader 时。 |
数据对象修改(Data-Object modification) | 每次修改现有 DataReader 的 QoS 时。 |
数据对象删除(Data-Object deletion) | 每次删除属于 DomainParticipant 的现有 DataReader 时。 |
8.5.4.4.3 SEDPbuiltinTopicsWriter 和 SEDPbuiltinTopicsReader
表 8.79 描述了 SEDPbuiltinTopicsWriter 和 SEDPbuiltinTopicsReader 的 HistoryCache。
表 8.79 - SEDPbuiltinTopicsWriter 和 SEDPbuiltinTopicsReader 的 HistoryCache 内容
方面 | 描述 |
数据类型(DataType) | DiscoveredTopicData |
基数(Cardinality) | DomainParticipant 创建的主题数量。DomainParticipant 创建的每个主题与存储在 builtinTopicsWriter 的 WriterHistoryCache 中描述该主题的数据对象之间存在一对一的对应关系。 |
数据对象插入(Data-Object insertion) | 每次在 DomainParticipant 中创建主题时。 |
数据对象修改(Data-Object modification) | 每次修改现有主题的 QoS 时。 |
数据对象删除(Data-Object deletion) | 每次删除属于 DomainParticipant 的现有主题时。 |
8.5.5 与 RTPS 虚拟机的交互
为了进一步说明 SPDP 和 SEDP,本规范描述了 SPDP 提供的信息如何被用于在 RTPS 虚拟机中配置 SEDP 内置端点。
8.5.5.1 发现新的远程参与者
使用 SPDPbuiltinParticipantReader,本地参与者 'local_participant' 发现了由 DiscoveredParticipantData participant_data 描述的另一个参与者的存在。被发现的参与者使用 SEDP。
下面的伪代码配置了 local_participant 中的本地 SEDP 内置端点,以便与被发现的参与者中的相应 SEDP 内置端点进行通信。
请注意,端点的配置方式取决于协议的实现。对于有状态的参考实现,此操作执行以下逻辑步骤:
// Check that the domainId of the discovered participant equals the local one. // If it is not equal then there the local endpoints are not configured to // communicate with the discovered participant. IF ( participant_data.domainId != local_participant.domainId ) THEN RETURN; ENDIF // Check that the domainTag of the discovered participant equals the local one. // If it is not equal then there the local endpoints are not configured to // communicate with the discovered participant. IF ( !STRING_EQUAL(participant_data.domainTag, local_participant.domainTag) ) THEN RETURN; ENDIF IF ( PUBLICATIONS_DETECTOR IS_IN participant_data.availableEndpoints ) THEN guid = <participant_data.guidPrefix, ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR>; writer = local_participant.SEDPbuiltinPublicationsWriter; proxy = new ReaderProxy( guid, participant_data.metatrafficUnicastLocatorList, participant_data.metatrafficMulticastLocatorList); writer.matched_reader_add(proxy); ENDIF IF ( PUBLICATIONS_ANNOUNCER IS_IN participant_data.availableEndpoints ) TH guid = <participant_data.guidPrefix, ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER>; reader = local_participant.SEDPbuiltinPublicationsReader; proxy = new WriterProxy( guid, participant_data.metatrafficUnicastLocatorList, participant_data.metatrafficMulticastLocatorList); reader.matched_writer_add(proxy); ENDIF IF ( SUBSCRIPTIONS_DETECTOR IS_IN participant_data.availableEndpoints ) TH guid = <participant_data.guidPrefix, ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR>; writer = local_participant.SEDPbuiltinSubscriptionsWriter; proxy = new ReaderProxy( guid, participant_data.metatrafficUnicastLocatorList, participant_data.metatrafficMulticastLocatorList); writer.matched_reader_add(proxy); ENDIF IF ( SUBSCRIPTIONS_ANNOUNCER IS_IN participant_data.availableEndpoints ) guid = <participant_data.guidPrefix, ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER>; reader = local_participant.SEDPbuiltinSubscriptionsReader; proxy = new WriterProxy( guid, participant_data.metatrafficUnicastLocatorList, participant_data.metatrafficMulticastLocatorList); reader.matched_writer_add(proxy); ENDIF IF ( TOPICS_DETECTOR IS_IN participant_data.availableEndpoints ) THEN guid = <participant_data.guidPrefix, ENTITYID_SEDP_BUILTIN_TOPICS_DETECTOR>; writer = local_participant.SEDPbuiltinTopicsWriter; proxy = new ReaderProxy( guid, participant_data.metatrafficUnicastLocatorList, participant_data.metatrafficMulticastLocatorList); writer.matched_reader_add(proxy); ENDIF IF ( TOPICS_ANNOUNCER IS_IN participant_data.availableEndpoints ) THEN guid = <participant_data.guidPrefix, ENTITYID_SEDP_BUILTIN_TOPICS_ANNOUNCER>; reader = local_participant.SEDPbuiltinTopicsReader; proxy = new WriterProxy( guid, participant_data.metatrafficUnicastLocatorList, participant_data.metatrafficMulticastLocatorList); reader.matched_writer_add(proxy); ENDIF
8.5.5.2 移除先前发现的参与者
基于远程参与者的 leaseDuration,本地参与者 'local_participant' 得出结论,带有 GUID_t participant_guid 的先前发现的参与者不再存在。参与者 'local_participant' 必须重新配置与由 GUID_t participant_guid 标识的参与者中的端点通信的任何本地端点。
对于有状态的参考实现,此操作执行以下逻辑步骤:
guid = <participant_guid.guidPrefix, ENTITYID_SEDP_BUILTIN_PUBLICATIONS_DETECTOR>; writer = local_participant.SEDPbuiltinPublicationsWriter; proxy = writer.matched_reader_lookup(guid); writer.matched_reader_remove(proxy); guid = <participant_guid.guidPrefix, ENTITYID_SEDP_BUILTIN_PUBLICATIONS_ANNOUNCER>; reader = local_participant.SEDPbuiltinPublicationsReader; proxy = reader.matched_writer_lookup(guid); reader.matched_writer_remove(proxy); guid = <participant_guid.guidPrefix, ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_DETECTOR>; writer = local_participant.SEDPbuiltinSubscriptionsWriter; proxy = writer.matched_reader_lookup(guid); writer.matched_reader_remove(proxy); guid = <participant_guid.guidPrefix, ENTITYID_SEDP_BUILTIN_SUBSCRIPTIONS_ANNOUNCER>; reader = local_participant.SEDPbuiltinSubscriptionsReader; proxy = reader.matched_writer_lookup(guid); reader.matched_writer_remove(proxy); guid = <participant_guid.guidPrefix, ENTITYID_SEDP_BUILTIN_TOPICS_DETECTOR>; writer = local_participant.SEDPbuiltinTopicsWriter; proxy = writer.matched_reader_lookup(guid); writer.matched_reader_remove(proxy); guid = <participant_guid.guidPrefix, ENTITYID_SEDP_BUILTIN_TOPICS_ANNOUNCER>; reader = local_participant.SEDPbuiltinTopicsReader; proxy = reader.matched_writer_lookup(guid); reader.matched_writer_remove(proxy);
8.5.6 支持替代发现协议
根据部署场景的不同,对参与者和端点发现协议的要求可能会有所不同。例如,针对速度和简单性进行优化的协议(如在局域网中的嵌入式设备中部署的协议)可能不适合在广域网环境中的大型系统。
因此,RTPS 规范允许实现支持多个 PDP 和 EDP。实现发现协议的方法有很多,包括使用静态发现、基于文件的发现、中央查找服务等。RTPS 为了互操作性的目的强加的唯一要求是,所有 RTPS 实现都至少支持 SPDP 和 SEDP。预计随着时间的推移,将开发一系列可互操作的发现协议,以满足特定的部署需求。
如果实现支持多个 PDP,每个 PDP 可能以不同的方式初始化,并发现不同的远程参与者集。使用不同供应商 RTPS 实现的远程参与者必须至少使用 SPDP 进行联系,以确保互操作性。当远程参与者使用相同的 RTPS 实现时,没有这样的要求。
即使所有参与者都使用 SPDP,远程参与者仍然可能使用不同的 EDP。参与者支持的 EDP 是通过 SPDP 交换的信息包含的。所有参与者都必须至少支持 SEDP,因此他们总是至少有一个 EDP 共同。然而,如果两个参与者都支持另一个 EDP,可以使用这种替代协议。在这种情况下,没有必要创建 SEDP 内置端点,或者如果它们已经存在,没有必要将它们配置为匹配新的远程参与者。这种方法使供应商可以根据需要自定义 EDP,而不影响互操作性。