3、HSMS 消息类型:Select.req、Select.rsp、Deselect.req、Deselect.rsp、Linktest.req、Linktest.rsp、Separate.req
HSMS(High-Speed SECS Message Services)定义了七种核心控制消息,用于管理 TCP/IP 连接之上的会话生命周期、连接活性检测以及正常断开。这些消息不携带设备工艺数据,而是负责通信链路的建立、维护与拆除。理解每种消息的语义、触发条件与响应规则,是设计可靠重连策略的基础。
3.1 消息类型总览
下表列出了七种 HSMS 控制消息的编码、方向与基本功能:
| 消息名称 | 消息编码(Session ID 后第 1 字节) | 方向 | 功能简述 |
|---|---|---|---|
| Select.req | 0x01 | 主动方 → 被动方 | 请求建立逻辑连接(会话) |
| Select.rsp | 0x02 | 被动方 → 主动方 | 响应 Select 请求,返回接受/拒绝 |
| Deselect.req | 0x03 | 任一端 → 对端 | 请求拆除指定逻辑连接 |
| Deselect.rsp | 0x04 | 对端 → 请求方 | 响应 Deselect 请求 |
| Linktest.req | 0x05 | 任一端 → 对端 | 探测 TCP 连接是否仍存活 |
| Linktest.rsp | 0x06 | 对端 → 请求方 | 响应 Linktest 请求 |
| Separate.req | 0x09 | 任一端 → 对端 | 通知对端即将断开 TCP 连接 |
提示: 消息编码 0x07 和 0x08 在标准中保留未使用。Separate.req 使用 0x09 而非 0x07,这是 HSMS 规范中一个容易记混的细节。
3.2 Select.req / Select.rsp:会话建立
TCP 连接建立后,HSMS 层必须通过 Select 流程将原始 TCP 套接字提升为具备设备 ID 和会话标识的逻辑连接。Select.req 由主动连接方(通常是主机)发出,被动方(通常是设备)回复 Select.rsp。
- Select.req 触发条件: TCP 三次握手完成,且底层 Socket 可写。
- Select.rsp 响应码:
- 0x00 — 接受(Success)
- 0x01 — 拒绝,连接已存在(Already Selected)
- 0x02 — 拒绝,资源不足(Not Ready)
- 0x03 — 拒绝,设备 ID 冲突或无效
- 重连影响: 重连时必须重新发送 Select.req,即使之前已成功建立过会话。旧会话不会自动恢复。
关键参数调优: Select.req 超时时间(T3 或 T7)通常设为 10–45 秒。如果设备在重连后响应缓慢,可适当增大此值,但不宜超过 60 秒,否则会延迟重连失败检测。
3.3 Deselect.req / Deselect.rsp:会话拆除
Deselect 用于在保持 TCP 连接的情况下释放逻辑会话。与 Separate 不同,Deselect 不关闭底层 TCP 连接,仅清除 HSMS 层的会话状态。
- 典型使用场景: 主机需要切换设备 ID,或设备需要临时释放会话资源但不断开 TCP。
- 重连策略关联: 在优雅重连流程中,建议先发送 Deselect.req 再发送 Separate.req,确保对端资源正确释放。
- 响应码:
- 0x00 — 成功
- 0x01 — 失败,会话不存在
3.4 Linktest.req / Linktest.rsp:连接保活
Linktest 是 HSMS 层的心跳机制,用于检测 TCP 连接是否在应用层仍然有效。即使 TCP 层面未断开,中间网络设备(如防火墙、NAT 网关)可能已静默丢弃连接,Linktest 能及时发现此类“僵尸连接”。
| 参数 | 推荐值 | 说明 |
|---|---|---|
| Linktest 发送间隔(T6) | 30–120 秒 | 两次 Linktest.req 之间的空闲等待时间 |
| Linktest 响应超时 | 5–15 秒 | 发送 Linktest.req 后等待 Linktest.rsp 的最大时间 |
| 最大重试次数 | 2–3 次 | 超时后重发 Linktest.req 的次数,超过则判定连接断开 |
避坑提醒: Linktest 间隔不宜过短(< 15 秒),否则会增加 CPU 和网络开销;也不宜过长(> 300 秒),否则无法及时检测到连接中断。建议根据现场网络稳定性动态调整。
3.5 Separate.req:连接断开通知
Separate.req 是 HSMS 层主动通知对端即将关闭 TCP 连接的信号。收到 Separate.req 的一方应停止发送数据,并准备关闭 Socket。
- 发送时机: 应用层决定断开连接时,先发送 Separate.req,再关闭 TCP Socket。
- 无响应消息: Separate.req 不需要对端回复 Separate.rsp,规范中不存在此消息。
- 重连场景: 如果设备突然断电或网络闪断,Separate.req 可能无法送达。重连策略必须能处理“无 Separate 通知”的异常断开。
3.6 HSMS 消息交互流程(SVG 图)
下图展示了从 TCP 连接到正常通信、保活检测、再到断开的全流程中,七种 HSMS 控制消息的出现位置与交互顺序:
3.7 消息超时与重试参数
每种 HSMS 控制消息都有对应的超时计时器(Timer),这些参数直接影响重连的灵敏度和稳定性:
| 计时器 | 关联消息 | 默认值(秒) | 调优建议 |
|---|---|---|---|
| T3 | Select.req → Select.rsp | 45 | 网络延迟高时增至 60,但不超过 90 |
| T4 | Linktest.req → Linktest.rsp | 45 | 建议缩短至 10–15 秒以快速检测断连 |
| T5 | Separate.req 发送后等待关闭 | 10 | 保持默认,无需调整 |
| T6 | Linktest.req 发送间隔 | 0(禁用) | 建议启用并设为 30–120 秒 |
| T7 | Select.req 重试间隔 | 10 | 重连场景可缩短至 3–5 秒 |
重连策略核心原则: 在重连过程中,优先使用较短的 T7 和 T4 值,以快速完成 Select 和 Linktest 流程;正常通信阶段则使用较长的 T6 间隔,避免心跳流量过多。建议实现“动态计时器切换”机制。
3.8 消息状态机与异常处理
HSMS 通信实体内部维护一个有限状态机,七种控制消息驱动状态迁移。以下是关键状态与消息的对应关系:
- NOT_SELECTED: TCP 已连接但未建立会话。只接收 Select.req,忽略其他控制消息。
- SELECTED: 会话已建立。可收发数据消息、Linktest、Deselect、Separate。
- LINK_TEST: 正在等待 Linktest.rsp。超时后回到 NOT_SELECTED 并触发重连。
- NOT_CONNECTED: TCP 未连接。所有控制消息均无效,需先建立 TCP 连接。
异常场景处理建议:
- 收到 Select.rsp 响应码 0x01(Already Selected):应发送 Deselect.req 清除旧会话,再重新 Select。
- 连续 3 次 Linktest 无响应:立即关闭 Socket,进入 NOT_CONNECTED 状态并启动重连。
- 收到 Separate.req 后:停止发送数据,关闭 Socket,等待重连计时器触发。
避坑提醒: 不要在收到 Separate.req 后立即重连。应等待至少 2 秒(建议 5 秒),避免对端 Socket 尚未完全关闭导致连接被拒。同时,重连前必须重置所有 HSMS 状态机变量。