【问题标题】:Paho MQTT (C++) client fails to connect to MosquittoPaho MQTT (C++) 客户端无法连接到 Mosquitto
【发布时间】:2017-11-04 21:25:55
【问题描述】:

我有使用 Paho MQTTPacket Embedded C++ 库连接到 MQTT 代理的 C++ 代码。当该经纪人是 io.adafruit.com 时,它工作得非常好。但是当它是我自己的 Mosquitto 实例在我的 Raspberry Pi 上运行时,连接失败。在 MQTT::Client::connect 方法中,我已将其缩小到 MQTTClient.h 中的这一行:

// this will be a blocking call, wait for the connack
if (waitfor(CONNACK, connect_timer) == CONNACK)

应用程序在这里挂起大约 30 秒,然后得到一个不是 CONNACK 的结果(特别是 0 而不是 2)。

我已经尝试过协议版本 3(即 3.1)和协议版本 4(即 3.1.1);同样的结果。

我的 Mosquitto 实例没有设置身份验证或密码。我尝试在 Mosquitto 日志中打开调试消息,但它们没有显示任何有用的信息。我不知所措。为什么我可能无法从我的 C++ Paho 代码连接到 Mosquitto?

编辑:这是客户端代码...再次,这适用于 Adafruit,但是当我将它指向本地主机上的 Mosquitto 时,它会按描述挂起。 (我已经省略了用户名和密码——我正在发送它们,但我真的不认为这是问题所在,因为在命令行上使用 mosquitto_pub 或 mosquitto_sub,我可以不管这个连接,因为 mosquitto 配置为允许匿名连接。)

const char* host = "127.0.0.1";
int port = 1883;
const char* clientId = "ZoomBridge";
const char* username = "...";
const char* password = "...";
MQTT::QoS subsqos = MQTT::QOS2;

ipstack = new IPStack();
client = new MQTT::Client<IPStack, Countdown, 30000>(*ipstack);

MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
data.willFlag = 1;
data.MQTTVersion = 3;
data.clientID.cstring = (char*)clientId;
data.username.cstring = (char*)username;
data.password.cstring = (char*)password;

data.keepAliveInterval = 20;
data.cleansession = 1;

int rc = ipstack->connect(host, port);
if (rc != MQTT::SUCCESS) {
    cout << "Failed [1] (result " << rc << ")" << endl;
    return rc;
}

rc = client->connect(data);
if (rc != MQTT::SUCCESS) {
    cout << "Failed [2] (result " << rc << ")" << endl;
    ipstack->disconnect();
    return rc;
}

【问题讨论】:

  • 你用的是什么版本的 mosquitto?
  • mosquitto 版本 1.4.10(构建日期 Mon,2017 年 5 月 29 日 13:43:29 +0100),上周下载并安装。上周,这个 Pi 上的一切都是新鲜的,包括操作系统。
  • 好的,只是检查默认的 raspbian 捆绑版本是非常旧的 iirc(最新的是 1.4.14,跳过 1.4.13,因为它有一个错误)
  • 您可能还想添加您的代码,以便我们看看是否有什么奇怪的地方。
  • 这是一个可能的线索:当我在选项中设置 data.willFlag = 0 而不是 1 时,它似乎可以工作。所有示例代码都使用 willFlag = 1,我找不到任何关于这意味着什么的文档。翻转这个标志我会改变什么?

标签: c++ mqtt mosquitto paho


【解决方案1】:

如 cmets 中所述。

您似乎正在设置标志以表明您想为客户端 (data.willFlag = 1;) 设置最后遗嘱和遗嘱,但随后不为 LWT 传递任何主题或有效负载。

如果您不需要 LWT,则将该标志设置为 0(或删除线路设置标志),因为它应该默认为禁用。

还值得一提的是,这都是Paho Embedded C++ MQTTPacket client,而不是完整的Paho C++ client

【讨论】:

  • 已确认:如果我设置了 data.will.message.cstring 和 data.will.topicName.cstring (以及 .qos 和 .retained 字段以获得良好的衡量标准),那么即使在.willFlag = 1。或者,正如你所说,我可以将标志设置为 0,这也可以。