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
相关产品推荐
相关产品推荐

