我正在尝试为我的家庭应用程序创建一个简单的MQTT客户端,并且正在使用libmosquittopp(这是libmosquitto的C++版本)。
该库的文档不多,但是我发现了两个示例(herehere),这些示例帮助我为“MQTTWrapper”类创建了代码。

这是我的代码:

MQTTWrapper.h:

#pragma once

#include <mosquittopp.h>
#include <string>

class MQTTWrapper : public mosqpp::mosquittopp
{
public:
    MQTTWrapper(const char* id, const char* host_, int port_);
    virtual ~MQTTWrapper();

    void myPublish(std::string topic, std::string value);
private:
    void on_connect(int rc);
    void on_publish(int mid);

    std::string host;
    int port;
};

MQTTWrapper.cpp
#include "MQTTWrapper.h"

#include <iostream>

MQTTWrapper::MQTTWrapper(const char* id, const char* host_, int port_) :
    mosquittopp(id), host(host_), port(port_)
{
    mosqpp::lib_init();

    int keepalive = 10;
    if (username_pw_set("sampleuser", "samplepass") != MOSQ_ERR_SUCCESS) {
        std::cout << "setting passwd failed" << std::endl;
    }
    connect_async(host.c_str(), port, keepalive);
    if (loop_start() != MOSQ_ERR_SUCCESS) {
        std::cout << "loop_start failed" << std::endl;
    }
}

MQTTWrapper::~MQTTWrapper()
{
    std::cout << "1" << std::endl;
    if (loop_stop() != MOSQ_ERR_SUCCESS) {
        std::cout << "loop_stop failed" << std::endl;
    }
    std::cout << "2" << std::endl;
    mosqpp::lib_cleanup();
    std::cout << "3" << std::endl;
}

void MQTTWrapper::on_connect(int rc)
{
    std::cout << "Connected with code " << rc << "." << std::endl;
}

void MQTTWrapper::myPublish(std::string topic, std::string value) {
    int ret = publish(NULL, topic.c_str(), value.size(), value.c_str(), 1, false);
    if (ret != MOSQ_ERR_SUCCESS) {
        std::cout << "Sending failed." << std::endl;
    }
}

void MQTTWrapper::on_publish(int mid) {
    std::cout << "Published message with id: " << mid << std::endl;
}

和我的main():
#include <iostream>
#include <string>
#include "MQTTWrapper.h"

int main(int argc, char *argv[])
{
    MQTTWrapper* mqtt;
    mqtt = new MQTTWrapper("Lewiatan IoT", "my.cloudmqtt.host", 12345);

    std::string value("Test123");
    mqtt->myPublish("sensors/temp", value);

    std::cout << "about to delete mqtt" << std::endl;
    delete mqtt;
    std::cout << "mqtt deleted" << std::endl;
    return 0;
}

对不起,这么多代码。

我的问题是,当我编译并执行它时-我的应用程序在loop_stop()方法上的MQTTWrapper析构函数中无限挂起(我只等待了9分钟)。
在libmosquittopp 1.4.8(debian软件包)上进行了测试,然后从github中使用1.4.9版删除了它。
loop_start()loop_stop(bool force=false)应该启动/停止一个单独的线程来处理消息传递。

我已经用强制停止(loop_stop(true))测试了它,但是这样我的应用程序停止了并且不发布任何数据。另一方面,loop_stop()发布数据,但随后暂停。

控制台输出(make && ./executable):
g++ -c MQTTWrapper.cpp
g++ -c main.cpp
g++ -o executable main.o MQTTWrapper.o -lmosquittopp
about to delete mqtt
1
Connected with code 0.
Published message with id: 1
(here it hangs infinitely...)

我的问题:
为什么此loop_stop()挂起以及如何解决?

(赞赏任何文档/教程/示例)

最佳答案

尝试在disconnect()之前调用loop_stop()。您还应该记住,您正在有效地执行此操作:

connect_async();
loop_start();
loop_stop();

客户端可能甚至没有机会进行连接,也没有在您告诉线程停止之前实际启动了线程。

值得考虑在回调中运行操作:
on_connect -> call publish
on_publish -> call disconnect

09-25 15:13