设备上下线常见问题

更新时间:
复制为 MD 格式

MQTT 客户端突然不重连怎么办?

如果强依赖自动重连,建议在业务层做兜底检查重连:检测客户端的连接状态,如果连接状态持续为断开状态,说明重连失败或网络异常,此时应销毁当前客户端并重新创建一个新的客户端连接。

检测客户端连接状态的方式:

1、定时发送消息。如果客户端离线,则发送消息时会抛出异常,此时可以触发重连。

2、订阅上下线通知消息。收到下线通知时可以触发重连。

设备上下线状态检测需要多长时间?

上线状态检测基本是实时的,因为上线请求默认视为一个心跳包。

下线状态检测:

如果是客户端主动断开连接,客户端会主动通知服务端,服务端能够立即感知下线状态。如果是意外断连(例如程序阻塞导致无法发送心跳),服务端需要等待约 1.5 倍心跳超时时间后才能检测到下线状态。

如何在新连接建立时立即断开旧的 Client ID 连接,避免 Client ID 冲突?

1)对于客户端断电再上电的场景,无法通过 isConnected 判断客户端是否仍在线。此时直接发起连接即可,服务端会因 Client ID 冲突自动断开旧连接并清理其在内存中的资源。

注意:isConnected 用于检查 TCP 连接是否存在。

2)其他大部分场景,如果需要重连,建议先通过 isConnected 判断是否仍在线。如果仍在线,则先调用 disconnect 断开连接,再重新建立连接。

MQTT 连接重试的机制是什么?

MQTT 连接重试时,如果在 ConnectionTimeout 内未连接成功,则不会继续重试。

connectionLost 回调中的重连:连接建立成功后,如果发生异常断开,会触发此回调进行重试。

setAutomaticReconnect(true) 的重连:控制正常断开连接后是否自动重连。

注意:如果首次连接即失败,则以上两种机制均不会触发重试。

控制台上设备上下线状态为什么显示无序?

由于上下线消息在分布式环境中是无序的,控制台上展示的客户端 connect 和 close 事件可能不按时间顺序排列。您可以根据 channelId 判断是否属于同一个连接。

No Heartbeat 导致断连如何解决?

No Heartbeat 断连通常是由于客户端阻塞,无法按时发送心跳导致的。

请检查以下两个参数的设置值:

mqttConnectOptions.setKeepAliveInterval(90);

mqttConnectOptions.setConnectionTimeout(5000);

如果通过公网访问,建议将心跳间隔设置为大于 60 秒。生产环境建议使用内网访问,MQTT 内网基于 Anytunnel,不区分 VPC,所有内网环境均可访问。

断开重连时报 Client ID 冲突是什么原因?

在 connectionLost 回调中重连时,不需要新建 MQTT Client 实例,直接使用原有实例重连即可。如果重新创建了 MQTT Client 实例,会导致 Client ID 冲突。

image.png