MQTT - 使用 Arduino 保持活动状态

物联网 MQTT 阿杜伊诺
2021-06-27 08:47:42

我正在为我的 IOT 设备使用 MQTT 代理,主要是 ESP8266(有些是 NodeMCU,有些是 Wemos mini,有些是 Sonoff),运行 Arduino 代码,一段时间(大约一年)。MQTT 代理在 RasppberryPi 零 W 上完美运行。

所有设备都使用我自己创建的库,包括 wifi 连接和 MQTT 以及为我的 IOT 设计的功能。

某些设备(20 个中的 2 个或 3 个) -定义 30 秒后继续offline使用keepAliveMQTT 中的功能(PubSub库是正确的)进入状态第二个Availabiliy状态转到offline它更新回online.

现在我试图找出它的原因有一段时间了,这就是我决定分享的原因:

  1. 如前所述,代码大多是通用的,我的 wifi+mqtt 对所有人都是一样的。
  2. 如果是由于 wifi 信号不好导致 MQTT 失去与服务器的连接,它应该reset在这种情况下使用看门狗计时器启动命令(重置 20 秒)。
  3. 我试图为那个特定的 IOT 更改 MQTT 代理,以确保它与代理无关……但问题仍然存在。

我的问题是:

  1. 如果#define MQTT_KEEPALIVE 30按照定义PubSub.h- 每 30 秒只检查一次,或者在该时间间隔内检查超过 1 次?
  2. 是否有另一种方法可以检查物联网设备与代理失去连接、进入keepAlive阶段并在发送 lastwill 后立即返回的原因或可能是什么原因
2个回答

keepalive 值作为连接请求的一部分发送给代理。代理使用此值启动一个计时器,该计时器开始倒计时。

每次客户端向代理发送数据包时,它都会重置计时器。这包括发布、响应发送到客户端的高 QOS 消息、订阅/取消订阅主题的请求。

如果计时器到期(在 30 秒),则代理将向客户端发送一个 PINGREQ 数据包,客户端应使用 PINGREP 数据包回复该数据包,从而重置计时器。

如果计时器用完并且代理没有收到来自客户端的 PINGREP 数据包,代理将等待另一个 0.5 * 保持活动时间(在本例中为 PINGREQ 的 15 秒),然后再为客户端发布任何 LWT 并进行标记它断开连接。客户端不处理任何保活处理(除了响应 PINGREQ)。

因此,如果客户端在发送 PINGREQ 前 5 秒崩溃,那么看门狗将在代理发布 LWT 后立即重置设备,并且它将几乎立即再次重新连接(并显示为在线)。

我有一个类似的问题,虽然我希望经纪人的行为像hardillb在他们的回答中描述的那样,但我仍然会超时。为了解决这个问题,我最终以略小于超时时间的间隔从客户端发送了一个 MQTT ping。这解决了问题,但对我来说似乎效率低下。

我当时无法嗅探网络流量,所以我不确定代理是否没有发送 PINGREQ 数据包,或者客户端连接是否没有正确响应 PINGREP。