写在开篇·蓉儿继续答疑
上回说到,郭靖搞清楚了DDS自动关联的本质——不是魔法,是“对暗号”。开发阶段双方约定好同一个Topic名字,运行时DDS听暗号,暗号相同就自动连。
郭靖合上笔记本,但眉头还是皱着:
“蓉儿,我还有三个疑问——”
“第一,发布者和订阅者启动有先后顺序吗?如果订阅者先启动,发布者后启动,还能连上吗?”
“第二,DDS的广播和一般的UDP广播一样吗?会不会把网络搞乱?”
“第三,发布者是一直在发数据吗?发送的数据有顺序吗?会不会后面的数据比前面的先到?”
黄蓉咬了口糖葫芦:“问得好!这三个问题,是DDS从‘能用’到‘用好’的关键。今天就把这三个疑问彻底讲清楚。”
一、疑问一:发布和订阅有先后顺序吗?
郭靖问:“如果域控制器先启动,摄像头后启动,还能连上吗?”
黄蓉画了一个时间轴:
┌─────────────────────────────────────────────────────────────────────┐ │ 启动顺序不影响最终连接 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 时间轴: │ │ │ │ t1:域控制器启动 │ │ └── 创建DataReader,广播:“我要收 /camera/front” │ │ └── 没找到匹配的Writer,进入等待状态 │ │ │ │ t2:摄像头启动(过了几秒) │ │ └── 创建DataWriter,广播:“我要发 /camera/front” │ │ └── 域控制器收到广播:“暗号对上了!” │ │ │ │ t3:自动建立连接,开始传数据 │ │ │ └─────────────────────────────────────────────────────────────────────┘
| 场景 | 能连上吗 | 说明 |
|---|---|---|
| 订阅者先启动,发布者后启动 | ✅ 能 | 订阅者进入等待,发布者上线后自动匹配 |
| 发布者先启动,订阅者后启动 | ✅ 能 | 发布者广播,订阅者上线后收到广播,自动匹配 |
| 同时启动 | ✅ 能 | 互相收到广播,自动匹配 |
| 一方永远不启动 | ❌ 不能 | 暗号永远对不上 |
结论:启动顺序不影响最终连接。谁先谁后无所谓,DDS会持续广播,直到暗号对上。
郭靖:“那如果域控启动时,摄像头还没启动,域控会一直等吗?”
黄蓉:“不会‘傻等’,它会持续监听。域控的DataReader创建后,DDS底层会定期广播‘我要收这个Topic’。一旦摄像头上线广播‘我要发’,域控立刻就能收到并建立连接。不需要人工干预。”
二、疑问二:DDS的广播和一般UDP广播一样吗?
郭靖问:“DDS底层也是用UDP广播吗?那车上几十个ECU都广播,网络会不会炸?”
黄蓉:“DDS的‘广播’不是无脑广播,而是有策略的。”
| 对比项 | 普通UDP广播 | DDS的发现广播 |
|---|---|---|
| 频率 | 应用想发就发 | 启动时多发,稳定后少发 |
| 范围 | 整个网络 | 同一Domain(逻辑隔离) |
| 内容 | 任意数据 | 只发发现信息(暗号),不发业务数据 |
| 业务数据 | 广播发送 | 建立连接后,业务数据是单播(点对点) |
关键点:DDS的广播只用于“发现阶段”。一旦发布者和订阅者匹配成功,后续的业务数据走单播,不广播。
黄蓉画了数据流向:
┌─────────────────────────────────────────────────────────────────────┐ │ 发现阶段 vs 数据传输阶段 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 【发现阶段】广播 │ │ ┌─────────┐ │ │ │ 摄像头 │ ──广播“我要发/camera/front”──→ 全网 │ │ └─────────┘ │ │ ┌─────────┐ │ │ │ 域控 │ ──广播“我要收/camera/front”──→ 全网 │ │ └─────────┘ │ │ │ │ 【匹配成功后】业务数据走单播 │ │ ┌─────────┐ ┌─────────┐ │ │ │ 摄像头 │ ──单播(点对点)────→ │ 域控 │ │ │ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘
结论:发现广播是轻量级的,业务数据是单播。不用担心网络被广播风暴淹没。
三、疑问三:数据是一直发吗?有顺序吗?
郭靖问:“摄像头采集到图像就发,那是一直在发吗?发送的数据有顺序吗?会不会后面的数据比前面的先到?”
黄蓉分三个小问题回答。
3.1 数据是一直发吗?
| 场景 | 行为 | 说明 |
|---|---|---|
| 摄像头(30fps) | 每33ms发一帧 | 周期性发送,有数据就发 |
| 刹车指令 | 有刹车动作才发 | 事件触发发送,没有就不发 |
| 温度传感器 | 每秒发一次 | 周期性发送 |
DDS不强制发送频率。发多快、发不发,完全由应用决定。DDS只负责“发出去”和“收得到”。
3.2 数据有顺序吗?
黄蓉画了一个例子:
┌─────────────────────────────────────────────────────────────────────┐ │ 数据的顺序保证 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ 摄像头发送顺序: │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │帧1 │→│帧2 │→│帧3 │→│帧4 │ ← 按采集顺序发送 │ │ └─────┘ └─────┘ └─────┘ └─────┘ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ 网络传输(可能乱序) │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │帧1 │ │帧3 │ │帧2 │ │帧4 │ ← 网络可能让帧3先到 │ │ └─────┘ └─────┘ └─────┘ └─────┘ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ DDS接收端(根据writerSN重排) │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │帧1 │→│帧2 │→│帧3 │→│帧4 │ ← DDS按序列号恢复顺序 │ │ └─────┘ └─────┘ └─────┘ └─────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘
DDS保证:同一Writer发送的数据,按发送顺序到达订阅者。即使网络乱序,DDS底层也会根据writerSN(序列号)重新排序,上层应用收到的数据顺序和发送顺序一致。
3.3 不同Writer的数据,有顺序吗?
郭靖追问:“那如果两个摄像头同时发数据,域控收到的顺序有保证吗?”
黄蓉摇头:
不同Writer之间的数据,没有顺序保证。摄像头A的第5帧和摄像头B的第3帧,谁先到谁后到,DDS不保证顺序。
| 场景 | 顺序保证 |
|---|---|
| 同一个Writer(同一个摄像头) | ✅ 有保证,按发送顺序到达 |
| 不同Writer(两个摄像头) | ❌ 无保证,谁先到谁先收 |
四、完整总结:三个疑问的答案
黄蓉画了一张总结表:
| 疑问 | 答案 |
|---|---|
| 发布订阅有先后顺序吗? | 没有顺序要求。谁先启动都行,DDS会持续广播,直到暗号对上自动连接 |
| 广播和普通UDP广播一样吗? | 不一样。只用于发现阶段,业务数据走单播,不会造成广播风暴 |
| 数据是一直发吗? | 取决于应用。DDS不强制频率,应用想发就发 |
| 数据有顺序吗? | 同一个Writer有顺序保证(按发送顺序到达);不同Writer无顺序保证 |
五、黄蓉的小本本
郭靖翻开她的笔记本,上面写着:
DDS通信行为要点:
1. 启动顺序:无所谓谁先谁后。DDS持续广播,暗号对上自动连。
2. 广播策略:发现阶段用轻量广播,业务数据用单播。不会造成网络风暴。
3. 发送频率:应用自己决定。周期发送(如摄像头30fps)或事件触发(如刹车指令)。
4. 顺序保证:
同一Writer:有顺序保证(writerSN重排乱序)
不同Writer:无顺序保证
一句话:发布订阅不挑顺序,发现广播点到即止;发送频率自己定,同源数据不乱序。
写在最后
郭靖合上笔记本:“我明白了。启动顺序不影响连接,DDS会持续广播直到暗号对上。发现广播是轻量的,业务数据是单播,不会把网络搞乱。数据发多快由应用决定,同一个摄像头的数据有顺序保证,不同摄像头之间没有。”
黄蓉咬了口糖葫芦:“全明白了?”
郭靖点头:“明白了。发布订阅不挑顺序,数据发送自己定。”
打完收工,886。