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

1.6 KiB
Raw Blame History

心跳机制

  • 边缘主机通过心跳机制来判断主机是否存活(解决弱网环境下websocket链接会经常断开的问题)
  • 边缘主机定期发送 UDP 心跳包,服务端按照 iot_host 的心跳检测周期判断是否有收到心跳包。
  • 如果 UDP 心跳丢失但 SSL channel 仍然存在,服务端不会把 host 标记为离线。
  • 如果 UDP 心跳丢失且 SSL channel 也不存在,服务端会把 host 标记为离线。

udp服务器

  • 端口: 18080

心跳包格式

旧格式 <<Len:16, HostUUID/binary>> 已不再接受。

当前心跳包格式:

<<
    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 的计算内容为前面所有字段:

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。