Search code examples
asynchronousbackgroundclientmqttmosquitto

Async mosquitto client trying to re-connect with mosquitto broker


Trying to implement an asynchronous client based in mosquitto MQTT broker, running forever in the background. My purpose is create a client able to connect / reconnect to broker in case the broker becomes offline at some time. I expected all connection / reconnection logic was managed by mosquitto callbacks (event-driven). However, this code doesn't try to connect to broker in case you try to run the client when the broker is stopped (offline) at initial time:

struct mosquitto *broker;
char ip[INET_ADDRSTRLEN]; // broker ip address
int port; // 1883
int keepalive; // 60
bool running = true;


int main(void)
{
    mosquitto_lib_init();
    broker = mosquitto_new(NULL, true, NULL);

    mosquitto_connect_callback_set(broker, on_connect_callback);
    mosquitto_disconnect_callback_set(broker, on_disconnect_callback);
    mosquitto_message_callback_set(broker, on_message_callback);

    mosquitto_connect_async(broker, ip, port, keepalive);
    mosquitto_loop_start(broker);


    while(running) {
        pause();
    }
}

After some testing, replaced

mosquitto_connect_async(broker, ip, port, keepalive);

by a while loop polling for the first success returned by mosquitto_connect_async function:

bool connected_to_broker = false;
while (!connected_to_broker) {
    rc = mosquitto_connect_async(broker, ip, port, keepalive);
    if (rc == MOSQ_ERR_SUCCESS) {
        connected_to_broker = true;
    } else {
        sleep(retry_timeout);
    }
}

After the while loop, it seems all the source code can be based on mosquitto callbacks.

Is this the expected way to manage this situation? Or should be managed in a different way? Thanks!


Solution

  • You don't have to make multiple connection attempts. Your problem is that the first attempt fails for the same reason but does not yet fire any callbacks because the communication thread is not yet started.

    If you check the return value of mosquitto_connect_async you will see it is MOSQ_ERR_ERRNO with errno being set to ECONNREFUSED (111).

    If mosquitto_loop_start is called before your first connection attempt, the disconnect callback should be fired - also with rc == MOSQ_ERR_ERRNO and errno == ECONNREFUSED