iot_cloud/docs/heartbeat.md
2026-05-30 15:25:40 +08:00

45 lines
1.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 心跳机制
* 边缘主机通过心跳机制来判断主机是否存活(解决弱网环境下websocket链接会经常断开的问题)
* 边缘主机定期发送 UDP 心跳包,服务端按照 `iot_host` 的心跳检测周期判断是否有收到心跳包。
* 如果 UDP 心跳丢失但 SSL channel 仍然存在,服务端不会把 host 标记为离线。
* 如果 UDP 心跳丢失且 SSL channel 也不存在,服务端会把 host 标记为离线。
### udp服务器
* 端口: 18080
### 心跳包格式
旧格式 `<<Len:16, HostUUID/binary>>` 已不再接受。
当前心跳包格式:
```erlang
<<
Version:8,
UuidLen:16,
UUID:UuidLen/binary,
Timestamp:64/unsigned-big,
Nonce:16/binary,
Mac:32/binary
>>
```
字段说明:
| 字段 | 说明 |
| --- | --- |
| `Version` | 当前固定为 `1`。 |
| `UuidLen` | `UUID` 的字节数。 |
| `UUID` | efka 对应的 host UUID。 |
| `Timestamp` | 秒级 Unix 时间戳。服务端只接受 120 秒时间窗内的心跳。 |
| `Nonce` | 16 字节随机数,必须加入 HMAC payload使同一秒内多次心跳的 Mac 不同。当前服务端不保存 nonce。 |
| `Mac` | HMAC-SHA256 结果32 字节。 |
`Mac` 的计算内容为前面所有字段:
```erlang
Payload = <<Version:8, UuidLen:16, UUID:UuidLen/binary, Timestamp:64/unsigned-big, Nonce:16/binary>>,
Mac = crypto:mac(hmac, sha256, HeartbeatSecret, Payload)
```
服务端在 `efka_client_store:verify_heartbeat/4` 中校验时间窗和 HMAC。`HeartbeatSecret` 使用 `SHA256(Token)`,其中 `Token` 和 TLS 鉴权使用同一个 auth token。`iot` 侧只保存派生后的 `heartbeat_secret`,不保存明文 token。