1

I'm writing an MQTT client which simply connects to the broker, and publishes or subscribes to a topic. Here in the program, I try to Connect to Broker and then call the loop_forever() function and is execute successfully and gets a connect acknowledgment at the client side, but instead of loop_forever(), when I called the loop_Start() for the new thread to execute all callback, it failed with the error MOSQ_ERR_NOT_SUPPORTED. Here is a code for the MQTT client for publisher and subscriber.

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;
}

I used visual studio 2022 and added all mosquito dependencies to the project. while running program with the loop_start() function I get this error: **Error in loop_start: 10**

  • 1
    [The docs](https://mosquitto.org/api/files/mosquitto-h.html#mosquitto_loop_start) say "MOSQ_ERR_NOT_SUPPORTED if thread support is not available". So my guess would be you are using a library compiled without thread support (which [appears](https://github.com/eclipse/mosquitto/issues/2707) to be the case with the default Windows installation). – Brits Apr 07 '23 at 23:35
  • So what configuration required to support thread brits? – Piyush Malaviya Apr 09 '23 at 03:03
  • Confirmation of the above is [here](https://github.com/eclipse/mosquitto/blob/master/README-windows.txt) "libmosquitto on Windows is currently compiled without thread support"... You will need to build from source; instructions are [here](https://github.com/eclipse/mosquitto#building-from-source). Note that threading under windows relies on the "old pthreads-win32" so there may be issues (there is a reason the standard build does not include it) - version 2.1 should [reintroduce this](https://github.com/eclipse/mosquitto/blob/develop/ChangeLog.txt#L152). – Brits Apr 10 '23 at 21:00
  • Yes Brits, Thanks for your answer, I build the mosquitto lib manually with Pthread-win32 in Windows and can run the MQTT client for subscribe and publish. @Brits: Is Mosquitto MQTT Client automatically reconnected if Broker goes down and up again? Any Idea about it? I used the loop_start() for thread other than the main thread. – Piyush Malaviya Apr 13 '23 at 04:34
  • Yes - see [the docs](https://mosquitto.org/api/files/mosquitto-h.html#mosquitto_reconnect). I'll add an answer to close off this question. – Brits Apr 13 '23 at 04:57

1 Answers1

0

The docs say loop_Start() returns "MOSQ_ERR_NOT_SUPPORTED if thread support is not available". This will be because "libmosquitto on Windows is currently compiled without thread support". This means you will need to rebuild the library with thread support (instructions).

This should no longer be necessary when version 2.1 is released.

Brits
  • 14,829
  • 2
  • 18
  • 31