1. 项目概述:FastDDS中的EDP心跳机制
在FastDDS(前身为FastRTPS)这个高性能DDS实现中,端点发现协议(Endpoint Discovery Protocol,简称EDP)是保证分布式节点动态发现的核心机制。其中心跳(heartbeat)和确认应答(acknack)消息的处理,直接关系到通信链路的可靠性和实时性。今天我们就来深入源码层面,看看FastDDS是如何在EDP阶段处理这些关键控制消息的。
这个机制的重要性在于:当一个新的数据写入者(DataWriter)加入网络时,它需要通过周期性的heartbeat消息向潜在的读取者(DataReader)宣告自己的存在。而读取者则会回复acknack消息,告知写入者自己需要哪些数据片段。这个过程如果出现延迟或丢失,轻则导致数据传输延迟,重则造成通信中断。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心流程解析
2.1 EDP阶段的消息交互时序
在FastDDS的发现阶段,消息交互遵循严格的时序逻辑:
- 初始发现阶段:通过Participant Discovery Protocol(PDP)发现远程参与者
- 端点匹配阶段:EDP交换Writer和Reader的QoS信息
- 活跃状态维护:通过持续的心跳和应答保持连接活性
典型的消息序列如下:
plaintext复制Writer Reader
| ---- DATA(x) -------------------> |
| ---- HEARTBEAT(seq=x) ----------> |
| <---- ACKNACK(seq=x, bitmap=1) -- |
| ---- DATA(x+1) -----------------> |
2.2 心跳消息的数据结构
在FastDDS源码中,heartbeat消息通过RTPSMessageGroup类构建,核心字段包括:
cpp复制struct HeartBeatSubmessage {
EntityId_t readerId; // 目标读取者ID
EntityId_t writerId; // 发送者写入者ID
SequenceNumber_t firstSN; // 首个序列号
SequenceNumber_t lastSN; // 最后序列号
Count_t count; // 心跳计数器
};
关键参数说明:
firstSN和lastSN定义了当前写入者持有的数据范围count用于检测重复或丢失的心跳包- 当
readerId为ENTITYID_UNKNOWN时表示广播消息
2.3 acknack消息的响应逻辑
读取者在收到heartbeat后,会通过StatefulReader类处理并生成acknack响应。核心处理逻辑位于:
cpp复制void StatefulReader::processHeartbeat(
const GUID_t& write
