发送与接收
在Fast DDS中,消息的发送与接收确实会经过RTPS层、DDS层,最终到达应用层。这一流程体现了Fast DDS作为DDS(Data Distribution Service)标准实现的核心架构设计。以下是详细的分层解释:
一、Fast DDS层次架构
Fast DDS的架构自顶向下分为三层:
- 应用层(Application Layer)
- 开发者通过DDS API(如
DataWriter
/DataReader
)发布或订阅数据。 - 定义数据类型(通过IDL文件)、QoS策略、监听器等。
- 开发者通过DDS API(如
- DDS层(DDS Domain Layer)
- 实现DDS规范的核心逻辑,包括:
- 主题(Topic)管理
- QoS策略处理(可靠性、持久性、历史记录等)
- 数据匹配(发布者/订阅者发现)
- 类型系统(动态类型支持)
- 实现DDS规范的核心逻辑,包括:
- RTPS层(RTPS Protocol Layer)
- 实现RTPS(Real-Time Publish-Subscribe)协议,负责:
- 消息序列化/反序列化
- 网络传输(UDP/TCP/共享内存)
- 消息路由与发现
- 可靠性传输(ACK/NACK机制)
- 实现RTPS(Real-Time Publish-Subscribe)协议,负责:
二、消息发送流程(从应用层到网络)
1. 应用层调用
cpp
// 应用层代码示例 | |
DataWriter* writer = publisher->create_datawriter(topic, QoS); | |
writer->write(sample_data); // 触发数据发送 |
2. DDS层处理
- 数据封装:将应用数据包装为DDS格式的
CacheChange
。 - QoS策略应用:根据QoS配置(如可靠性、持久性)决定是否需要存储历史数据。
- 类型处理:通过
TypeSupport
进行类型擦除或动态类型序列化。
3. RTPS层处理
- 消息序列化:将
CacheChange
序列化为RTPS协议格式(CDR流)。 - 网络传输:
- 添加RTPS消息头(包括Writer GUID、序列号等元数据)。
- 通过选定的传输协议(UDP/TCP/SHM)发送数据包。
4. 底层网络传输
- 数据包通过网络接口卡(NIC)或共享内存传输到接收端。
三、消息接收流程(从网络到应用层)
1. RTPS层接收
- 网络接收:通过传输层接收原始数据包。
- 消息反序列化:解析RTPS消息头,提取序列化数据。
- 可靠性处理:
- 如果是可靠传输,处理ACK/NACK重传逻辑。
- 维护序列号状态机(确保消息按顺序接收)。
2. DDS层处理
- 数据匹配:
- 根据主题哈希、QoS兼容性过滤消息。
- 检查实例状态(如存活状态、数据有效性)。
- 历史缓存:
- 如果是持久化或历史记录QoS,将数据存入历史缓存。
- 触发
DataReader
的监听器或条件变量。
3. 应用层回调
cpp
// 应用层监听器示例 | |
class MyListener : public DataReaderListener { | |
void on_data_available(DataReader* reader) override { | |
SampleInfo info; | |
MyType data; | |
if (reader->take_next_sample(data, info) == ReturnCode_t::RETCODE_OK) { | |
// 处理接收到的数据 | |
} | |
} | |
}; |
- 数据交付:
- 通过
take_next_sample()
或监听器回调(on_data_available
)将数据传递给应用层。 - 应用层处理业务逻辑(如解析数据、更新UI等)。
- 通过
四、关键交互点
- DDS-RTPS接口
CacheChange
对象:DDS层与RTPS层之间的数据载体,封装序列化后的数据和元数据。HistoryCache
:DDS层管理历史数据的模块,与RTPS层的可靠性机制紧密集成。
- QoS策略穿透
- 可靠性(Reliability):通过RTPS层的ACK/NACK机制实现。
- 持久性(Durability):DDS层的历史缓存与RTPS层的持久化传输协同工作。
- 线程模型
- 发送和接收通常在不同线程执行(如RTPS接收线程、DDS处理线程、应用回调线程)。
- 通过无锁队列或条件变量实现跨线程通信。
五、调试与验证
- 日志跟踪
- 启用RTPS层日志:
cpp
Log::SetVerbosity(Log::Kind::All); // 启用所有日志
- 观察RTPS消息的序列化/反序列化过程。
- 启用RTPS层日志:
- Wireshark抓包
- 过滤
rtps
协议,分析RTPS消息结构(如Submessage
类型、序列号)。
- 过滤
- 性能分析
- 使用Fast DDS的统计模块(
StatisticsModule
)监控各层延迟。
- 使用Fast DDS的统计模块(
六、总结
消息在Fast DDS中的流动路径为:
应用层(发布)→ DDS层(封装/QoS)→ RTPS层(序列化/传输)→ 网络 → RTPS层(反序列化/可靠性)→ DDS层(匹配/过滤)→ 应用层(订阅)
这一分层设计实现了:
- 协议标准化:通过RTPS层保证跨厂商互操作性。
- 功能解耦:DDS层专注数据分发逻辑,RTPS层专注高效传输。
- 性能优化:各层可独立优化(如DDS层的QoS处理、RTPS层的零拷贝传输)。