4. Entry类型详解:Find Service Entry、Offer Service Entry、Subscribe Eventgroup Entry、Stop Subscribe Eventgroup Entry
好,咱们今天来啃SOME/IP服务发现里最核心的四个Entry类型。说白了,整个服务发现过程,就是靠这四种报文在网络上“喊话”和“应答”。
我刚开始接触SOME/IP时,也被这四种Entry搞得有点晕。后来在项目里调了几个月bug,才真正摸透了它们的脾气。今天我把这些经验全盘托出,你跟着走一遍,保证能搞明白。
4.1 Find Service Entry(查找服务)
它是什么?
Find Service Entry,就是客户端在网络上“喊一嗓子”:“谁提供XX服务?报个名!”
这是一个广播报文,发往IP地址255.255.255.255,端口是SD端口(默认30490)。所有节点都能收到。
报文结构长啥样?
// Find Service Entry 关键字段
- Type: 0x00 (FindService)
- Service ID: 你要找的服务ID
- Instance ID: 你要找的实例ID(可以是通配符0xFFFF)
- Major Version: 主版本号
- TTL: 通常为3(表示只等3秒)
我个人的习惯:在调试阶段,我会把TTL设大一点,比如10秒。这样方便抓包分析。但量产时一定要改回3秒,否则网络负载会变大。
什么时候发Find?
- 客户端启动时,需要找某个服务
- 服务挂了,客户端需要重新发现
- 网络拓扑变化,客户端想确认服务还在不在
4.2 Offer Service Entry(提供服务)
它是什么?
Offer Service Entry,就是服务端在网络上“打广告”:“我提供XX服务,谁需要?来找我!”
这也是广播报文。服务端启动后,会主动发Offer,告诉所有节点自己上线了。
报文结构长啥样?
// Offer Service Entry 关键字段
- Type: 0x01 (OfferService)
- Service ID: 提供的服务ID
- Instance ID: 提供的实例ID
- Major Version: 主版本号
- Minor Version: 次版本号
- TTL: 生存时间(通常3秒,需要周期性重发)
- IPv4 Address: 服务端的IP地址
- Port: 服务端监听端口(通常是SOME/IP端口)
这里有个关键点:Offer报文里带了IP和端口。客户端收到后,就知道该往哪里发请求了。你想想看,如果没有这个信息,客户端连服务端在哪都不知道,怎么通信?
什么时候发Offer?
- 服务端启动时
- 周期性重发(TTL到期前)
- 服务端收到Find请求时(单播回复)
4.3 Subscribe Eventgroup Entry(订阅事件组)
它是什么?
Subscribe Eventgroup Entry,就是客户端向服务端“订阅”:“我想接收某个事件组的数据,请把我加入订阅列表!”
这是一个单播报文,客户端直接发给服务端。不是广播。
报文结构长啥样?
// Subscribe Eventgroup Entry 关键字段
- Type: 0x06 (SubscribeEventgroup)
- Service ID: 服务ID
- Instance ID: 实例ID
- Eventgroup ID: 要订阅的事件组ID
- TTL: 订阅有效期(通常3秒,需要周期性续订)
- IPv4 Address: 客户端的IP地址
- Port: 客户端接收事件的端口
为什么需要订阅?
说白了,事件组就是一组相关事件的集合。比如一个“车辆状态”事件组,可能包含车速、转速、水温等多个事件。客户端订阅了这个组,就能收到组里所有事件的通知。
我建议:在设计事件组时,不要把不相关的事件塞到一个组里。我在项目中遇到过,有人把“车窗状态”和“发动机转速”放在同一个事件组里。结果客户端只想看车窗,却被迫接收发动机数据,白白浪费带宽。
4.4 Stop Subscribe Eventgroup Entry(停止订阅事件组)
它是什么?
Stop Subscribe Eventgroup Entry,就是客户端告诉服务端:“我不再需要这个事件组了,把我从订阅列表里移除吧!”
这也是单播报文,客户端发给服务端。
报文结构长啥样?
// Stop Subscribe Eventgroup Entry 关键字段
- Type: 0x07 (StopSubscribeEventgroup)
- Service ID: 服务ID
- Instance ID: 实例ID
- Eventgroup ID: 要停止订阅的事件组ID
- TTL: 通常为0(表示立即停止)
什么时候需要发Stop?
- 客户端不再需要该事件组的数据
- 客户端即将关闭或休眠
- 客户端切换到另一个服务实例
这里有个细节:Stop报文的TTL通常设为0。为什么?因为TTL=0表示“立即失效”。服务端收到后,会立刻把客户端从订阅列表里移除,不再发送事件。
四种Entry的对比总结
| Entry类型 | 方向 | 报文类型 | 主要用途 | TTL典型值 |
|---|---|---|---|---|
| Find Service | 客户端→网络 | 广播 | 查找服务 | 3秒 |
| Offer Service | 服务端→网络 | 广播 | 宣告服务 | 3秒(需周期性重发) |
| Subscribe Eventgroup | 客户端→服务端 | 单播 | 订阅事件组 | 3秒(需周期性续订) |
| Stop Subscribe Eventgroup | 客户端→服务端 | 单播 | 取消订阅 | 0(立即停止) |
嗯,四种Entry就讲完了。你发现没有?其实整个服务发现流程,就是这四种报文在来回“对话”。客户端发Find,服务端回Offer;客户端发Subscribe,服务端开始推送事件;客户端发Stop,服务端停止推送。就这么简单。
下一章,咱们会深入讲讲这些Entry在具体项目里怎么配置、怎么调试。到时候我会拿几个真实案例出来,保证让你学得更扎实。