Adafruit mqtt 库中的 mqtt.ping()

mqtt.ping() in Adafruit mqtt library

以下代码来自 Adafruit Mqtt 文档:

// Adjust as necessary, in seconds.  Default to 5 minutes (300 seconds).
#define MQTT_CONN_KEEPALIVE 300

// ping the server to keep the mqtt connection alive
// NOT required if you are publishing once every KEEPALIVE seconds
if(! mqtt.ping()) {
   mqtt.disconnect();
}

"MQTT_CONN_KEEPALIVE" 的实际作用是什么?我无法弄清楚..如果我在这里编写如上所示的代码并将其放入我的循环中,那么 ping 会不断执行,并且所有数据包都被拒绝......我期待 MQTT_CONN_KEEPALIVE 变量是在 ping() 函数中使用,仅在 300 秒过去后才执行 ping,但 id 似乎并非如此。 我应该如何编写代码才能每隔几分钟 ping 一次?

MQTT Keep Alive 是 MQTT 协议的一部分,用于维护代理和客户端之间的连接。您可以在 documentation.

中阅读更多相关信息

MQTT 使用通常由客户端保持打开状态的 TCP/IP 连接,以便可以随时发送和接收数据。为了检测连接失败,MQTT 使用 ping 系统,如果在一定时间后没有发送消息 (KeepAlive),它会以预定的时间间隔向代理发送消息。

具体到Adafruit_MQTT的实现,如果你发布数据,你确定你会在MQTT_CONN_KEEPALIVE设置的时间段内发布数据,那你就可以了。

如果 server/broker 在 MQTT_CONN_KEEPALIVE + MQTT_CONN_KEEPALIVE 的额外 50% 内没有从客户端接收到数据或 PINGREQ,代理将断开与网络的连接(超时) 并且客户端将不得不重新建立连接。

因此,如果 MQTT 客户端仅订阅主题而不发布,则客户端必须每 MQTT_CONN_KEEPALIVE 秒至少向代理发送一次 ping (PINGREQ)。但是,您不想不断地对服务器执行 ping 操作。一种方法是每 MQTT_CONN_KEEPALIVE 秒只发送 mqtt.ping()。

#define MQTT_KEEP_ALIVE 300
unsigned long previousTime = 0;

loop() {
 
  if((millis() - previousTime) > MQTT_KEEP_ALIVE * 1000) {
    previousTime = millis();   
    if(! mqtt.ping()) {
      mqtt.disconnect();
    }
  }

  // do something else
}