[
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