eclipse / paho.mqtt.c

An Eclipse Paho C client library for MQTT for Windows, Linux and MacOS. API documentation: https://eclipse.github.io/paho.mqtt.c/
https://eclipse.org/paho
Other
1.96k stars 1.1k forks source link

LWT doesn't work #592

Closed topfs2 closed 5 years ago

topfs2 commented 5 years ago

I have trouble getting last will and testament to work, it get it to work in paho for python and in java, but C version eludes me.

I've altered the code you have on your home page, with the minor addition of will as a connection option.

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "MQTTClient.h"

#define ADDRESS     "tcp://localhost:1883"
#define CLIENTID    "ExampleClientPub"
#define TOPIC       "test"
#define PAYLOAD     "online"
#define PAYLOAD_OFF "offline"
#define QOS         1
#define TIMEOUT     10000L

int main(int argc, char* argv[])
{
    MQTTClient client;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    MQTTClient_willOptions will_opts = MQTTClient_willOptions_initializer;
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    MQTTClient_deliveryToken token;
    int rc;

    will_opts.topicName = TOPIC;
    will_opts.message = PAYLOAD_OFF;
    will_opts.qos = QOS;

    MQTTClient_create(&client, ADDRESS, CLIENTID,
        MQTTCLIENT_PERSISTENCE_NONE, NULL);
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;
    conn_opts.will = &will_opts;

    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        exit(-1);
    }
    pubmsg.payload = PAYLOAD;
    pubmsg.payloadlen = strlen(PAYLOAD);
    pubmsg.qos = QOS;

    MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
    printf("Waiting for up to %d seconds for publication of %s\n"
            "on topic %s for client with ClientID: %s\n",
            (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID);
    rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
    printf("Message with delivery token %d delivered\n", token);
    MQTTClient_disconnect(client, 10000);
    MQTTClient_destroy(&client);
    return rc;
}

This I would expect should yield "online" and then "offline" when doing mosquitto_sub -t test -v

Here is the code with a cmake file if that makes it easier to test, I've just built paho c with

cmake .
make
sudo make install

example.zip

Let me know if I should upload the example in some other fashion?

fpagliughi commented 5 years ago

The LWT is only sent out by the server if the client connection is lost unexpectedly - meaning without a proper disconnect. Since you're calling MQTTClient_disconnect, you are getting a proper disconnect and the server is throwing away the LWT without sending it. Which is what it is supposed to do.

Try commenting out the MQTTClient_disconnect() call and see what happens if you exit the application without cleanly disconnecting the client. In that case, the server should emit the LWT.

topfs2 commented 5 years ago

OMG thank you thank you thank you!

That explains why I got it to work in java, I didn't bother with the disconnect there :)