You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mosquitto MQTT Client调用loop_start()返回错误10求助

MQTT客户端loop_start()返回MOSQ_ERR_NOT_SUPPORTED错误排查

问题现象

编写的MQTT客户端调用loop_forever()时可正常连接Broker并收到连接确认,但改用loop_start()启动线程处理回调时,返回错误MOSQ_ERR_NOT_SUPPORTED(错误码10)。开发环境为Visual Studio 2022,已添加所有Mosquitto依赖项。

客户端代码

myMosq.h

#include <mosquittopp.h>
#include <mosquitto.h>

class myMosq : public mosqpp::mosquittopp
{
private:
    const char* host;
    const char* id;
    const char* topic;
    int         port;
    int         keepalive;

    void on_connect(int rc);
    void on_disconnect(int rc);
    void on_publish(int mid);
    void on_message(const struct mosquitto_message* message);

public:
    myMosq(const char* id, const char* _topic, const char* host, int port);
    ~myMosq();
    bool send_message(const char* _message);
};

myMosq.cpp

#include <iostream>

myMosq::myMosq(const char* _id, const char* _topic, const char* _host, int _port) : mosquittopp(_id)
{
    mosqpp::lib_init() ;        // Mandatory initialization for mosquitto library

    this->keepalive = 60;    // Basic configuration setup for myMosq class
    this->id = _id;
    this->port = _port;
    this->host = _host;
    this->topic = _topic;

    int result;
    result = connect_async(host, port, keepalive);     // non blocking connection to broker request
    if (result != MOSQ_ERR_SUCCESS)
    {
        std::cerr << "Error in connect_async" << std::endl;
    }
    result = loop_start();            // Start thread managing connection / publish/subscribe
    //result = loop_forever();            // Start thread managing connection / publish / subscribe
    if (result != MOSQ_ERR_SUCCESS)
    {
        std::cerr << "Error in loop_start: " << (mosq_err_t)result << std::endl;
    }
};

myMosq::~myMosq() 
{
    loop_stop();            // Kill the thread
    mosqpp::lib_cleanup();    // Mosquitto library cleanup
}

bool myMosq::send_message(const  char* _message)
{
    int ret = publish(NULL, this->topic, strlen(_message), _message, 1, false);
    return (ret == MOSQ_ERR_SUCCESS);
}

void myMosq::on_disconnect(int rc) 
{
    std::cout << ">>> myMosq - disconnection(" << rc << ")" << std::endl;
}

void myMosq::on_connect(int rc)
{
    if (rc == 0){
        std::cout << ">>> myMosq - connected with server" << std::endl;
    }
    else{
        std::cout << ">>> myMosq - Impossible to connect with server(" << rc << ")" << std::endl;
    }
}

void myMosq::on_publish(int mid)
{
    std::cout << ">>> myMosq - Message (" << mid << ") succeed to be published " << std::endl;
}

void myMosq::on_message(const struct mosquitto_message* message)
{
    std::cout << "Topic: " << message->topic << " Payload: " << message->payload << " Payload_Length: " << message->payloadlen << std::endl;
}

main.cpp

#include <windows.h>
#include <string>

#include "myMosq.h"

void MQTT_Subscriber(myMosq& i_client)
{
    int result = i_client.subscribe(nullptr, "logrequest", 1);
    if (result != MOSQ_ERR_SUCCESS)
    {
        std::cout << "mosquitto : subscriber error: " << mosqpp::strerror(result) << std::endl;
    }
    else
    {
        std::cout << "mosquitto : subscriber : " << result << std::endl;
    }
}

void MQTT_Publisher(myMosq& i_client)
{
    int i = 1;
    std::string message = "I am mosquitto VS pub";
    while (1)
    {
        std::string message1 = message + std::to_string(i);
        if (!i_client.send_message(message1.c_str()))
        {
            break;
        }
        Sleep(2000);
        i++;
    }
}

int main()
{
    std::cout << "In main" << std::endl;

    std::shared_ptr<myMosq> m_client = std::make_shared<myMosq>("dev3_", "logrequest", "127.0.0.1", 1883);

    //MQTT_Publisher(m_client);
    //MQTT_Subscriber(m_client);

    while (1);
    return 0;
}

问题原因

loop_start()是Mosquitto的线程模式接口,需要库在编译时启用线程支持(开启WITH_THREADING编译选项)。如果当前使用的Mosquitto库没有启用该选项,调用loop_start()就会返回MOSQ_ERR_NOT_SUPPORTED错误。而loop_forever()是单线程阻塞模式,不需要线程支持,因此可以正常运行。

解决方法

1. 重新编译带线程支持的Mosquitto库

  • 下载Mosquitto官方源码包
  • 使用CMake配置编译参数:
    • 勾选WITH_THREADING选项(默认可能未启用)
    • 选择与VS2022匹配的编译架构(x86或x64)
    • 配置生成动态库或静态库,完成编译

2. 更新项目依赖

  • 将编译好的带线程支持的mosquitto.lib/mosquitto.dll替换到项目的依赖目录中
  • 在VS2022项目属性中,更新包含目录、库目录和链接器输入,指向新编译的库文件

3. 验证修复

重新编译客户端项目,运行后loop_start()应能正常启动线程,不再返回错误码10。

额外提示

  • 若使用预编译Mosquitto库,需确认其是否明确支持线程;多数预编译包默认不包含线程支持,建议自行编译
  • 确保mosqpp::lib_init()在所有Mosquitto操作前调用(代码中已正确实现)
  • 线程模式下,避免在主线程和回调线程中同时修改客户端对象状态,防止竞态问题

内容的提问来源于stack exchange,提问作者Piyush Malaviya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:34:56