为什么设备会频繁上下线

我在制作一个物联网应用,我是用EMQX开源版本作为我的MQTT服务器。
硬件上我使用有人云的DTU网关设备(DR - 154)通过MQTT协议与我的网站通讯。
我在网站上通过订阅EMQX的系统主题来捕获设备的上线和下线状态并在上线或者下线时发通知消息在前端网站。

我的DTU网关设置的心跳时间是60秒,在测试中我的网站会频繁的收到设备的下线和上线的通知,他们几乎一起发生,似乎是设备下线后又立马上线了。 下面是DTU在EMQX控制台上显示的配置截图:

EMQX追踪日志:
emqx@trace_dr154_2023-10-08.zip (5.3 KB)

请教大神们这种情况一般都是什么原因和解决方案,谢谢

设备网络信号怎么样

您好。请问多个设备是否使用了相同的clientid?MQTT使用clientid来唯一标识设备。如果多个设备使用相同的clientid,后面的设备连接时就会把之前连接的设备踢掉。

没有,clientid都是唯一的,在9约26号之前还算稳定不怎么频繁发生,但是从26号开始就频繁这样了

这套组合在9月份已经跑了1个月了,从9-26号开始才频繁出现这种问题,设备位置没有变,物联网卡也还有钱和流量,所以不确定是不是设备信号的事

从我上传的追踪日志能看出来啥吗?

从日志看,要么是多个设备使用了相同的clientid,要么是一个设备自己重新发起连接。

grep -e “term|CON” emqx@trace_dr154_2023-10-08.log
2023-10-08T15:32:58.333275+08:00 [MQTT] 00501923551700018760@46.103.19.207:52129 msg: mqtt_packet_received, packet: CONNECT(Q0, R0, D0, ClientId=00501923551700018760, ProtoName=MQTT, ProtoVsn=4, CleanStart=false, KeepAlive=60, Username=admin, Password=)
2023-10-08T15:32:58.451454+08:00 [SOCKET] 00501923551700018760@46.103.19.207:52128 msg: emqx_connection_terminated, reason: {shutdown,takenover}
2023-10-08T15:32:58.452022+08:00 [MQTT] 00501923551700018760@46.103.19.207:52129 msg: mqtt_packet_sent, packet: CONNACK(Q0, R0, D0, AckFlags=1, ReasonCode=0)
2023-10-08T15:34:33.390408+08:00 [MQTT] 00501923551700018760@46.103.19.207:52130 msg: mqtt_packet_received, packet: CONNECT(Q0, R0, D0, ClientId=00501923551700018760, ProtoName=MQTT, ProtoVsn=4, CleanStart=false, KeepAlive=60, Username=admin, Password=
)
2023-10-08T15:34:33.476516+08:00 [SOCKET] 00501923551700018760@46.103.19.207:52129 msg: emqx_connection_terminated, reason: {shutdown,takenover}
2023-10-08T15:34:33.477682+08:00 [MQTT] 00501923551700018760@46.103.19.207:52130 msg: mqtt_packet_sent, packet: CONNACK(Q0, R0, D0, AckFlags=1, ReasonCode=0)
2023-10-08T15:49:08.883950+08:00 [MQTT] 00501923551700018760@46.103.19.207:52131 msg: mqtt_packet_received, packet: CONNECT(Q0, R0, D0, ClientId=00501923551700018760, ProtoName=MQTT, ProtoVsn=4, CleanStart=false, KeepAlive=60, Username=admin, Password=******)
2023-10-08T15:49:08.964333+08:00 [SOCKET] 00501923551700018760@46.103.19.207:52130 msg: emqx_connection_terminated, reason: {shutdown,takenover}
2023-10-08T15:49:08.965040+08:00 [MQTT] 00501923551700018760@46.103.19.207:52131 msg: mqtt_packet_sent, packet: CONNACK(Q0, R0, D0, AckFlags=1, ReasonCode=0)

  1. ClientId=00501923551700018760发起连接请求
    2023-10-08T15:32:58.333275+08:00 [MQTT] 00501923551700018760@46.103.19.207:52129 msg: mqtt_packet_received, packet: CONNECT(Q0, R0, D0, ClientId=00501923551700018760, ProtoName=MQTT, ProtoVsn=4, CleanStart=false, KeepAlive=60, Username=admin, Password=******)

  2. 因为这个连接请求的clientid与“00501923551700018760@46.103.19.207:52128”的一样,所以这个连接“00501923551700018760@46.103.19.207:52128“就断开了。
    2023-10-08T15:32:58.451454+08:00 [SOCKET] 00501923551700018760@46.103.19.207:52128 msg: emqx_connection_terminated, reason: {shutdown,takenover}

  3. 00501923551700018760@46.103.19.207:52129连接成功。
    2023-10-08T15:32:58.452022+08:00 [MQTT] 00501923551700018760@46.103.19.207:52129 msg: mqtt_packet_sent, packet: CONNACK(Q0, R0, D0, AckFlags=1, ReasonCode=0)

  4. 后面又来了相同clientid的请求,然后step 3中的连接就断开了。

我再次检查了下确定没有多个设备使用相同的ClientID,现在就剩一个原因是设备自己重新发起了连接,请问除了网络问题,还有哪些情况下设备会自动发起新连接呢?

从日志看,好像其他连接到EMQX的client发送了主题为“/modbus/rtu/device/00501923551700018760/1/down”的消息。这个消息是不是关闭“ClientId=00501923551700018760”这个客户端的命令?

2023-10-08T15:32:58.452022+08:00 [MQTT] 00501923551700018760@46.103.19.207:52129 msg: mqtt_packet_sent, packet: CONNACK(Q0, R0, D0, AckFlags=1, ReasonCode=0)
2023-10-08T15:34:26.887176+08:00 [MQTT] 00501923551700018760@46.103.19.207:52129 msg: mqtt_packet_sent, packet: PUBLISH(Q0, R0, D0, Topic=/modbus/rtu/device/00501923551700018760/1/down, PacketId=undefined, Payload(hex)=03040003000C01ED)
2023-10-08T15:34:28.452522+08:00 [SOCKET] 00501923551700018760@46.103.19.207:52129 msg: socket_force_closed, reason: keepalive_timeout
2023-10-08T15:34:33.390408+08:00 [MQTT] 00501923551700018760@46.103.19.207:52130 msg: mqtt_packet_received, packet: CONNECT(Q0, R0, D0, ClientId=00501923551700018760, ProtoName=MQTT, ProtoVsn=4, CleanStart=false, KeepAlive=60, Username=admin, Password=******)

您好,请问在相同Client ID这种情况下,能否设置为不把已连接的设备踢掉,而是给正在连接的设备返回错误信息?

这个命令不是关闭客户端的命令,是一个采集数据的指令,DTU和从机之间是使用Modbus连接的,所以需要发采集指令获取从机上的数据。

我现在猜测发生此问题的原因可能是由于物联网卡在发送心跳的时候ip或者端口会发生变化,导致EMQX认为这是一个新的连接,然后把之前的连接给关闭了,但是物联网卡的ip会经常变有是合理的,这好像是一个无解的问题啊

这个,真要抠起来,只能说这个clientID机制,没有真正实现好。除非修改源代码,自己编译一个版本。