在开发过程中你可能会遇到设备离线这种情况,我们现在来讲讲设备上下线这件事。先阐述一下概念:
云端在线(mqtt):是指从云端到设备这个网络是通的,与云端在线对立的概念是本地在线。
本地在线:客户端(app)和设备能通过近场通信连接,比如蓝牙连接、局域网连接。
不管是本地在线还是云端在线,对用户来说都设备都是处于一个可控状态。所以只要其中一种在线,app面板都会显示设备在线。
云端判定设备在线/离线逻辑
基本原则:
虚拟设备永远在线
低功耗设备永远在线,产品上打上低功耗标志
移除或不存在的设备永远离线
判断原理:
设备每 60s会向服务端发送一个ping包, 接下来如果42秒内没有收到服务端回复的pong(ping/pong用于测试tcp连接是否断开),设备端会发送rst包(异常关闭连接)直接强制断开tcp连接,显示离线原因为closed。
服务端每个隔连接75秒检查一次,没有完全依赖ping包做检测,服务端认为只要在心跳周期内收到任意设备上报的数据,该tcp链路即为正常。如果在两次检测周期均没有收到设备端任何数据,服务端认为设备已离线。
设备打印日志:
发送ping包:mqtt_ping -->>
收到ping ack包:mqtt_ping <<--
接收ping ack超时:respond timeout -->>
mqtt qos=1的包3次超时:qos1 package timeout, cnt:3
mqtt 连接关闭时:mqtt close
什么情况下设备会离线
设备没有给服务端发送ping包,比如设备断电、设备断网
网络异常
设备发送mqtt ping包后,42s没有收到云端的pong包,设备端断开连接,显示离线原因为closed。
云端如果在两次检测周期均没有收到设备端任何数据,服务端认为设备已离线(原因可能为设备直接断电,设备断网,设备重启等), 发送 (FIN, ACK) 包断开此tcp连接,走正常的四次挥手流程, 显示原因为 keepalive_timeout。
dp 上报未收到云端mqtt ack,连续3个dp上报都没有收到ack的话,则设备会主动关闭mqtt连接并重连。此时设备日志形如:qos1 package timeout
对于子设备,网关离线,子设备就离线(除蓝牙设备)
dp 上报未收到云端mqtt ack,连续3个dp上报都没有收到ack的话,则设备会主动关闭mqtt连接并重连。此时设备日志形如:qos1 package timeout
在ota时,由于http协议下载升级文件耗费较多带宽,可能导致mqtt上报ota进度超时,从而断开连接并重连
在设备与路由器短暂断开,然后重新连上时,如果设备IP发生了变化,则设备已有的mqtt连接将无效,此时设备在经过心跳包/dp上报,会检测到连接断开,并重连。
更多的设备离线排查指南请参考:
https://developer.tuya.com/cn/docs/iot- ... ngj01h9pvw
对设备上下线还有什么疑问的,欢迎在下方留言~