Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [mosquitto-dev] connect_async problem and advice publish/dedconnect needed

Hi.

Roger, indeed the 'if(rc)' conditional seems to be the problem. I rebuilt mosquitto, changing it to 'if(rc > 0)' as you suggested, and voilà, connect_async works. The function now returns MOSQ_ERR_SUCCESS as expected.
Karl, it did not matter if I used loop() or loop_start()/loop_end(), the behavior was the same.
Also loop_end() did not help with my problem with undelivered messages. But waiting for publish callbacks to fire, as you suggested, did the job. I include my (test) source code below. It can probably be done in a more elegant way, but for my use case, this will do.
Compiling it into an executable 'mqtt_c' now gives the following output:

> ./mqtt_c
synchronous connection to broker at localhost:1883
connack string: Connection Accepted.
connected to broker at localhost:1883
sending message 1 with QoS 0 on topic test/topic
published message with QoS 0
sending message 2 with QoS 1 on topic test/topic
published message with QoS 1
sending message 3 with QoS 2 on topic test/topic
published message with QoS 2
message 1 has been sent successfully
message 2 has been sent successfully
message 3 has been sent successfully
disconnected from broker (0)
Thank you, good bye.

> ./mqtt_c 1
asynchronous connection to broker at localhost:1883
connack string: Connection Accepted.
connected to broker at localhost:1883
sending message 1 with QoS 0 on topic test/topic
published message with QoS 0
sending message 2 with QoS 1 on topic test/topic
published message with QoS 1
sending message 3 with QoS 2 on topic test/topic
published message with QoS 2
message 1 has been sent successfully
message 2 has been sent successfully
message 3 has been sent successfully
disconnected from broker (0)
Thank you, good bye.

Subscribing to the topic test/# (using mosquitto_sub) shows me that all messages are delivered.
Thank you very much, guys.

Regards

Markus
________________

Source code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <mosquitto.h>

void on_publish(struct mosquitto *m, void *msg_published, int mid)
{
    printf("message %d has been sent successfully\n", mid);
    *((bool *)msg_published + (mid-1)*sizeof(bool)) = true;
}

void on_disconnect(struct mosquitto *m, void *o, int rc)
{
    printf("disconnected from broker (%d)\n", rc);
}

int main( int argc, char **argv )
{
    int msg_id = 0;
    bool msg_sent[3] = {false, false, false};
    bool all_msg_sent = false;
    bool async = argc > 1 ? atoi(argv[1]) : false;
    const char *host = "localhost";
    const int port = 1883;
    const char topic[] = "test/topic";
    char msg[30];
    int mlen, qos, status, i;
    struct mosquitto *m;

    if ( mosquitto_lib_init() != MOSQ_ERR_SUCCESS ) {
        perror("library initialization failed");
        exit(EXIT_FAILURE);
    }

    m = mosquitto_new(NULL, true, msg_sent);
    if ( m == NULL ) {
        perror("failed to create mosquitto instance");
        mosquitto_lib_cleanup();
        exit(EXIT_FAILURE);
    }

    printf("%s connection to broker at %s:%d\n", async ? "asynchronous" : "synchronous", host,
           port);
    status =
        async ? mosquitto_connect_async(m, host, port, 60) : mosquitto_connect(m, host, port, 60);
    printf("connack string: %s\n", mosquitto_connack_string(status));
    if ( status != MOSQ_ERR_SUCCESS ) {
        perror("could not connect to broker");
    }
    else {
        printf("connected to broker at %s:%d\n", host, port);
        // set callbacks
        mosquitto_disconnect_callback_set(m, on_disconnect);
        mosquitto_publish_callback_set(m, on_publish);
        status = mosquitto_loop_start(m);
        for ( qos = 0; qos <= 2; ++qos ) {
            ++msg_id;
            sprintf(msg, "my test message, QoS %d, id %d", qos, msg_id);
            mlen = strlen(msg);
            printf("sending message %d with QoS %d on topic %s\n", msg_id, qos, topic);
            if ( mosquitto_publish(m, &msg_id, topic, mlen, msg, qos, false) != MOSQ_ERR_SUCCESS ) {
                perror("failed to publish message");
            }
            else {
                printf("published message with QoS %d\n", qos);
            }

        }

        /* wait until all publish callbacks fired;
         * the publish callback sets msg_sent[mid - 1] for message id mid */
        do {
            all_msg_sent = true;
            for (i = 0; i < msg_id; ++i) {
                all_msg_sent = all_msg_sent && msg_sent[i];
            }
        } while (!all_msg_sent);

        mosquitto_disconnect(m);
        status = mosquitto_loop_stop(m, true);
    }

    mosquitto_destroy(m);
    mosquitto_lib_cleanup();

    printf("Thank you, good bye.\n");
    exit(EXIT_SUCCESS);
}
________________

-----Ursprüngliche Nachricht-----
Von: mosquitto-dev-bounces@xxxxxxxxxxx [mailto:mosquitto-dev-bounces@xxxxxxxxxxx] Im Auftrag von Karl Palsson
Gesendet: Dienstag, 28. April 2015 19:31
An: General development discussions for the mosquitto project
Betreff: Re: [mosquitto-dev] connect_async problem and advice publish/dedconnect needed


"Bayerlein, Markus (I/AEV-23)" <markus.bayerlein@xxxxxxx> wrote:
> Hi there.
> 
> As already stated in the email subject, I encounter two problems with
> the Mosquitto library and hope for some advice.
> 
> 1.     I can't connect to an MQTT broker using 'connect_async'. The
> return value of the function is '-1' (= MOSQ_ERR_CONN_PENDING). The
> connack string returned is 'Connection Refused: unknown reason.' and the
> error string is 'Operation now in progress ' The broker I try to connect
> to is mosquitto (v1.4.1). Using 'connect' works fine.

I see something like this, but it works when it reconnects.  Are you
using loop_start, or loop() directly?  I haven't dug any further in it
yet.

> 
> 2.     When I publish a message and disconnect immediately thereafter,
> the message sometimes is not sent (actually, it depends on the QoS:
> messages with QoS 0 or 1 are sometimes not sent, Qos 2 messages never) .
> If I do a sleep(1) before the disconnect, all messages are delivered
> correctly. I am sure there is a better solution than waiting for a
> second. How do I ensure that all messages are sent before a disconnect?


loop_stop() is a pretty good way of doing it.  Either that, or you have
to wait for all callbacks to fire as Roger mentions in the other reply


Back to the top