1、结构:
Fast DDS的架构如下图所示,可以看到以下不同环境的层模型:
- 应用层:利用Fast DDS API 在分布式系统中实现通信的用户应用程序。
- Fast DDS层:DDS 通信中间件的稳健实现。它允许部署一个或多个 DDS 域,其中同一域内的 DomainParticipants 通过在域主题下发布/订阅来交换消息。
- RTPS层:实施实时发布-订阅 (RTPS) 协议 ,以实现与 DDS 应用程序的互操作性。该层充当传输层的抽象层。
- 传输层:快速 DDS可用于各种传输协议,例如不可靠传输协议 (UDP)、可靠传输协议 (TCP) 或共享内存传输协议 (SHM)。
2、DDS层:
Fast DDS的 DDS 层定义了通信的几个关键元素。用户将在其应用程序中创建这些元素,从而合并 DDS 应用程序元素并创建以数据为中心的通信系统。 Fast DDS遵循DDS规范,将这些涉及通信的元素定义为实体。DDS实体是支持服务质量配置 (QoS) 并实现侦听器的任何对象。
- QoS:定义每个实体的行为的机制。
- Listener:向实体通知应用程序执行期间可能发生的事件的机制。
下面列出了 DDS 实体及其描述和功能:
- Domain:标识 DDS 域的正整数。每个DomainParticipant都会有一个分配的DDS域,以便同一域中的DomainParticipant可以通信,并隔离DDS域之间的通信。该值必须由应用程序开发人员在创建 DomainParticipants 时给出。
- DomainParticipant:包含其他 DDS 实体(例如发布者、订阅者、主题和多主题)的对象。它是允许创建其包含的先前实体以及配置其行为的实体。
- Publisher:发布者使用 DataWriter 发布主题下的数据,DataWriter 将数据写入传输。它是创建和配置其包含的 DataWriter 实体的实体,并且可能包含其中一个或多个。
- DataWriter:它是负责发布消息的实体。用户在创建该实体时必须提供一个主题,该主题将作为发布数据的主题。发布是通过将数据对象写入 DataWriterHistory 中的更改来完成的。
- DataWriterHistory:这是数据对象更改的列表。当 DataWriter 继续在特定主题下发布数据时,它实际上会在此数据中创建更改。正是这种变化被记录在历史中。然后,这些更改将发送到订阅该特定主题的 DataReader。
- Subscriber:订阅者使用 DataReader 订阅主题,DataReader 从传输中读取数据。它是创建和配置其包含的 DataReader 实体的实体,并且可能包含一个或多个 DataReader 实体。
- DataReader:它是订阅主题以接收出版物的实体。用户在创建该实体时必须提供订阅Topic。DataReader 接收其 HistoryDataReader 中发生更改的消息。
- DataReaderHistory:它包含DataReader 由于订阅某个主题而收到的数据对象的更改。
- Topic:将发布者的 DataWriter 与订阅者的 DataReader 绑定的实体。
3、RTPS层:
如上所述,Fast DDS中的 RTPS 协议允许从传输层抽象 DDS 应用实体。根据上图,RTPS 层有四个主要Entities。
- RTPSDomain:它是DDS域对RTPS协议的扩展。
- RTPSParticipant:包含其他 RTPS 实体的实体。它允许配置和创建它包含的实体。
- RTPSWriter:消息的来源。它读取 DataWriterHistory 中写入的更改,并将它们传输到之前匹配的所有 RTPSReader。
- RTPSReader:消息的接收实体。它将 RTPSWriter 报告的更改写入 DataReaderHistory 中。
4、传输层:
Fast DDS支持通过各种传输协议实施应用程序。它们是 UDPv4、UDPv6、TCPv4、TCPv6 和共享内存传输 (SHM)。默认情况下,DomainParticipant 实现 UDPv4 和 SHM 传输协议。
5、并发和多线程:
Fast DDS实现了并发多线程系统。每个 DomainParticipant 都会生成一组线程来处理后台任务,例如日志记录、消息接收和异步通信。这不会影响您使用该库的方式,即Fast DDS API 是线程安全的,因此您可以无所畏惧地从不同线程调用同一 DomainParticipant 上的任何方法。但是,当外部函数访问由库内部运行的线程修改的资源时,必须考虑这种多线程实现。一个示例是实体侦听器回调中修改的资源。
Fast DDS 生成的完整线程集如下所示。仅当使用适当的传输时才会创建与传输相关的线程(标记为 UDP、TCP 和 SHM 类型)。
Name | Type | Cardinality | Description |
---|---|---|---|
Event | General | 每个域参与者一个 | 处理周期性和触发时间事件 |
Discovery Server Event | General | 每个域参与者一个 | 同步对 Discovery Server数据库的访问 |
Asynchronous Writer | General | 每个启用的异步流量控制器一个最少 1。 | 管理异步写入。即使对于同步写入器,某些形式的通信也必须在后台启动。 |
Datasharing Listener | General | 每个数据读取器一个 | 处理通过数据共享接收到的消息的侦听器线程 |
Reception | UDP | 每个端口一个 | 处理传入UDP 消息的侦听器线程 |
Reception | TCP | 每个端口一个 | 处理传入TCP 消息的侦听器线程 |
Keep Alive | TCP | 每个端口一个 | 保持 TCP 连接的活动线程。 |
Reception | SHM | 每个端口一个 | 通过 SHM 段处理传入消息的侦听器线程 |
Logging | SHM | 每个 SHM 描述符一个 | 将传输的数据包存储并转储到文件中。 |
Watchdog | SHM | 一 | 监视打开的共享内存段的运行状况。 |
General Logging | Log | 一 | 累积并写入适当的消费者日志条目。 |
Security Logging | Log | 每个域参与者一个 | 累积并写入安全日志条目。 |
Watchdog | Filewatch | 一 | 跟踪监视文件的修改状态 |
Callback | Filewatch | 一 | 当监视的文件更改时运行注册的回调 |
其中一些线程仅在满足某些条件时才会产生:
- 仅当使用数据共享时才会创建数据共享侦听器线程。
- 仅当 DomainParticipant 配置为 Discovery Server SERVER 时,才会创建 Discovery Server 事件线程。
- TCP 保活线程要求保活周期配置为大于零的值。
- 安全日志记录和共享内存数据包日志记录线程都需要启用某些配置选项。
- 仅当使用FASTDDS_ENVIRONMENT_FILE时才会生成文件监视线程。
关于传输线程,Fast DDS 默认使用 UDP 和共享内存传输。可以配置端口配置以满足部署的特定需求,但默认配置是始终使用元流量端口和单播用户流量端口。这适用于 UDP 和共享内存,因为 TCP 不支持多播。
6、发现协议:
发现协议定义了在给定主题下发布的 DataWriter 和订阅同一主题的 DataReader 进行匹配的机制,以便它们可以开始共享数据。这适用于沟通过程中的任何时刻。 Fast DDS提供以下发现机制:
- 简单的发现:这是默认的发现机制,在RTPS 标准中定义 ,并提供与其他 DDS 实现的兼容性。这里,DomainParticipants 在早期阶段被单独发现,以便随后匹配它们实现的 DataWriter 和 DataReader。
- 发现服务器:这种发现机制使用集中式发现架构,其中服务器充当元流量发现的中心。
- 静态发现:这实现了 DomainParticipant 之间的发现,但如果远程 DomainParticipant 事先知道这些实体,则可以跳过每个 DomainParticipant (DataReader/DataWriter) 中包含的实体的发现。
- 手动发现:该机制仅与RTPS层兼容。它允许用户使用其选择的任何外部元信息通道手动匹配和取消匹配 RTPSParticipants、RTPSWriters 和 RTPSReaders。
7、安全:
Fast DDS可配置为通过在三个级别实现可插拔安全性来提供安全通信:
- 远程域参与者的身份验证:DDS :Auth:PKI-DH插件使用受信任的证书颁发机构 (CA) 和 ECDSA 数字签名算法提供身份验证来执行相互身份验证。它还使用椭圆曲线 Diffie-Hellman (ECDH) 密钥协商协议建立共享密钥。
- 实体的访问控制:DDS :Access:Permissions插件在 DDS 域和主题级别提供对 DomainParticipants 的访问控制。
- 数据加密:DDS :Crypto:AES-GCM-GMAC插件使用伽罗瓦计数器模式 (AES-GCM) 中的高级加密标准 (AES) 提供经过身份验证的加密。