Arduino 如果客户端重新连接,如何抑制MQTT Last Will消息?

Arduino 如果客户端重新连接,如何抑制MQTT Last Will消息?,arduino,mqtt,esp8266,mosquitto,Arduino,Mqtt,Esp8266,Mosquitto,我正在为Arduino和ESP8266使用EspMQTTClient库;但我的问题很可能适用于任何环境 客户端设置最后一条将在客户端丢弃时广播的消息。但是,如果客户端断开,然后立即重新连接,则我希望抑制该消息 由于客户端唯一ID是相同的,我认为这将是标准行为;但显然不是 因此,客户端将断开,并重新连接。我收到客户机发送的启动消息,然后收到最后一条遗嘱“客户机已死亡”消息。这是没有帮助的,因为看起来客户端再次死机,无法重新连接 在超时发生之前,如何抑制成功重新连接的客户端的“最后将”消息 编辑:下

我正在为Arduino和ESP8266使用EspMQTTClient库;但我的问题很可能适用于任何环境

客户端设置最后一条将在客户端丢弃时广播的消息。但是,如果客户端断开,然后立即重新连接,则我希望抑制该消息

由于客户端唯一ID是相同的,我认为这将是标准行为;但显然不是

因此,客户端将断开,并重新连接。我收到客户机发送的启动消息,然后收到最后一条遗嘱“客户机已死亡”消息。这是没有帮助的,因为看起来客户端再次死机,无法重新连接

在超时发生之前,如何抑制成功重新连接的客户端的“最后将”消息

编辑:下面是一些简化的代码,演示了该问题:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <EspMQTTClient.h>
#include "lwip/inet.h"
#include "lwip/dns.h"
#include "mqtt.h"
#include "secret.h"

#define SERVICE_NAME    "pc-control"

EspMQTTClient mqtt(SSID, PASSWORD, MQTT_SERVER, (String(SERVICE_NAME) + "/Example").c_str());;

void onConnectionEstablished() {
    mqtt.publish("Example", "ready");
}

void setup() {
    mqtt.enableLastWillMessage("Example", "dead", true);
}

void loop() {
    mqtt.loop();
    delay(100);
}

不,没有办法抑制最后的遗嘱(LWT)

但是如果你确定你使用的是一致的clientid,我认为它不应该发送它。您说您正在重置设备,这意味着代理将等待1.5*保持活动时间,然后断开客户端。只要设备在此之前与相同的clientid重新连接,或者应该在不触发LWT的情况下退出旧连接


我看不出您在发布的代码中设置了keep alive time或clientid,因此很难说得更多。我还将打开代理上的日志记录,以检查客户端是否与相同的clientid连接,并查看它是否正在退出以前的客户端。

如果遵循MQTT v3.1.1规范的代理检测到您已断开连接,则发布LWT是完全正确的。这是无法阻止的

@hardillb建议,如果连接已断开但代理没有注意到,那么在发送LWT之前,您必须使用keepalive*1.5重新连接。这是正确的。然而,这是一个很大的问题。然而,你依赖的是你失去的联系在经纪人那里得不到承认。它有时可能有效,但这不是我想要依赖的条件


如果此功能对您非常重要,那么您可能应该考虑改用MQTT v5。这将为您提供设置“会话到期间隔”的选项,即在发送LWT之前断开连接后保持会话活动的时间量。

在您的特定情况下,请尝试升级到MOSQUITO 1.6.3或更高版本。会话接管存在影响1.5.1到1.6.2的错误。

使用客户端代码和您正在使用的MOSQUITO版本更新问题,并包括在重新连接消息后看到LWT交付的订户的详细信息。是否可能服务名称始终被视为空,由于指针悬空,3.1不是MOSQUITO版本,即MQTT协议版本。mosquitto版本将是1.x,其中x最有可能是5或6。我不知道是否有任何嵌入式MQTT客户端库已经更新以支持MQTT v5
mosquitto_sub -t "#" -v
Example ready
<<<I reset the client here>>>
Example ready
Example dead