Paho Asynchronous MQTT C Client Library
Quality of service

The MQTT protocol provides three qualities of service for delivering messages between clients and servers: "at most once", "at least once" and "exactly once".

Quality of service (QoS) is an attribute of an individual message being published. An application sets the QoS for a specific message by setting the MQTTAsync_message.qos field to the required value.

A subscribing client can set the maximum quality of service a server uses to send messages that match the client subscriptions. The MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this maximum. The QoS of a message forwarded to a subscriber thus might be different to the QoS given to the message by the original publisher. The lower of the two values is used to forward a message.

The three levels are:

QoS0, At most once: The message is delivered at most once, or it may not be delivered at all. Its delivery across the network is not acknowledged. The message is not stored. The message could be lost if the client is disconnected, or if the server fails. QoS0 is the fastest mode of transfer. It is sometimes called "fire and forget".

The MQTT protocol does not require servers to forward publications at QoS0 to a client. If the client is disconnected at the time the server receives the publication, the publication might be discarded, depending on the server implementation.

QoS1, At least once: The message is always delivered at least once. It might be delivered multiple times if there is a failure before an acknowledgment is received by the sender. The message must be stored locally at the sender, until the sender receives confirmation that the message has been published by the receiver. The message is stored in case the message must be sent again.

QoS2, Exactly once: The message is always delivered exactly once. The message must be stored locally at the sender, until the sender receives confirmation that the message has been published by the receiver. The message is stored in case the message must be sent again. QoS2 is the safest, but slowest mode of transfer. A more sophisticated handshaking and acknowledgement sequence is used than for QoS1 to ensure no duplication of messages occurs.

@page publish Publication example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTAsync.h"
#define ADDRESS "tcp://localhost:1883"
#define CLIENTID "ExampleClientPub"
#define TOPIC "MQTT Examples"
#define PAYLOAD "Hello World!"
#define QOS 1
#define TIMEOUT 10000L
volatile MQTTAsync_token deliveredtoken;
int finished = 0;
void connlost(void *context, char *cause)
{
MQTTAsync client = (MQTTAsync)context;
int rc;
printf("\nConnection lost\n");
printf(" cause: %s\n", cause);
printf("Reconnecting\n");
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start connect, return code %d\n", rc);
finished = 1;
}
}
void onDisconnect(void* context, MQTTAsync_successData* response)
{
printf("Successful disconnection\n");
finished = 1;
}
void onSend(void* context, MQTTAsync_successData* response)
{
MQTTAsync client = (MQTTAsync)context;
int rc;
printf("Message with token value %d delivery confirmed\n", response->token);
opts.onSuccess = onDisconnect;
opts.context = client;
if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start sendMessage, return code %d\n", rc);
exit(EXIT_FAILURE);
}
}
void onConnectFailure(void* context, MQTTAsync_failureData* response)
{
printf("Connect failed, rc %d\n", response ? response->code : 0);
finished = 1;
}
void onConnect(void* context, MQTTAsync_successData* response)
{
MQTTAsync client = (MQTTAsync)context;
int rc;
printf("Successful connection\n");
opts.onSuccess = onSend;
opts.context = client;
pubmsg.payload = PAYLOAD;
pubmsg.payloadlen = strlen(PAYLOAD);
pubmsg.qos = QOS;
pubmsg.retained = 0;
deliveredtoken = 0;
if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start sendMessage, return code %d\n", rc);
exit(EXIT_FAILURE);
}
}
int main(int argc, char* argv[])
{
MQTTAsync client;
int rc;
MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
MQTTAsync_setCallbacks(client, NULL, connlost, NULL, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
conn_opts.onSuccess = onConnect;
conn_opts.onFailure = onConnectFailure;
conn_opts.context = client;
if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
{
printf("Failed to start connect, return code %d\n", rc);
exit(EXIT_FAILURE);
}
printf("Waiting for publication of %s\n"
"on topic %s for client with ClientID: %s\n",
PAYLOAD, TOPIC, CLIENTID);
while (!finished)
#if defined(WIN32) || defined(WIN64)
Sleep(100);
#else
usleep(10000L);
#endif
return rc;
}
MQTTAsync_responseOptions::context
void * context
Definition: MQTTAsync.h:606
MQTTAsync_token
int MQTTAsync_token
Definition: MQTTAsync.h:249
MQTTAsync_message_initializer
#define MQTTAsync_message_initializer
Definition: MQTTAsync.h:318
MQTTAsync_responseOptions_initializer
#define MQTTAsync_responseOptions_initializer
Definition: MQTTAsync.h:644
MQTTAsync
void * MQTTAsync
Definition: MQTTAsync.h:239
MQTTAsync_message::retained
int retained
Definition: MQTTAsync.h:300
MQTTAsync_setCallbacks
int MQTTAsync_setCallbacks(MQTTAsync handle, void *context, MQTTAsync_connectionLost *cl, MQTTAsync_messageArrived *ma, MQTTAsync_deliveryComplete *dc)
MQTTAsync_sendMessage
int MQTTAsync_sendMessage(MQTTAsync handle, const char *destinationName, const MQTTAsync_message *msg, MQTTAsync_responseOptions *response)
MQTTAsync_disconnect
int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions *options)
MQTTCLIENT_PERSISTENCE_NONE
#define MQTTCLIENT_PERSISTENCE_NONE
Definition: MQTTClientPersistence.h:74
MQTTAsync_message::payloadlen
int payloadlen
Definition: MQTTAsync.h:265
MQTTAsync_destroy
void MQTTAsync_destroy(MQTTAsync *handle)
MQTTAsync_successData
Definition: MQTTAsync.h:463
MQTTAsync_disconnectOptions::onSuccess
MQTTAsync_onSuccess * onSuccess
Definition: MQTTAsync.h:1195
MQTTASYNC_SUCCESS
#define MQTTASYNC_SUCCESS
Definition: MQTTAsync.h:119
MQTTAsync_disconnectOptions::context
void * context
Definition: MQTTAsync.h:1207
MQTTAsync_responseOptions
Definition: MQTTAsync.h:582
MQTTAsync_create
int MQTTAsync_create(MQTTAsync *handle, const char *serverURI, const char *clientId, int persistence_type, void *persistence_context)
MQTTAsync_disconnectOptions_initializer
#define MQTTAsync_disconnectOptions_initializer
Definition: MQTTAsync.h:1230
MQTTAsync_connectOptions::keepAliveInterval
int keepAliveInterval
Definition: MQTTAsync.h:1003
MQTTAsync_message::qos
int qos
Definition: MQTTAsync.h:281
MQTTAsync_message::payload
void * payload
Definition: MQTTAsync.h:267
MQTTAsync_connect
int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions *options)
MQTTAsync_message
Definition: MQTTAsync.h:257
MQTTAsync_connectOptions
Definition: MQTTAsync.h:980
MQTTAsync_failureData
Definition: MQTTAsync.h:428
MQTTAsync_responseOptions::onSuccess
MQTTAsync_onSuccess * onSuccess
Definition: MQTTAsync.h:594
MQTTAsync_failureData::code
int code
Definition: MQTTAsync.h:433
MQTTAsync_disconnectOptions
Definition: MQTTAsync.h:1179
MQTTAsync_connectOptions_initializer
#define MQTTAsync_connectOptions_initializer
Definition: MQTTAsync.h:1149
MQTTAsync.h
MQTTAsync_successData::token
MQTTAsync_token token
Definition: MQTTAsync.h:466
MQTTAsync_connectOptions::cleansession
int cleansession
Definition: MQTTAsync.h:1025
MQTTAsync_connectOptions::context
void * context
Definition: MQTTAsync.h:1082
MQTTAsync_connectOptions::onFailure
MQTTAsync_onFailure * onFailure
Definition: MQTTAsync.h:1076
MQTTAsync_connectOptions::onSuccess
MQTTAsync_onSuccess * onSuccess
Definition: MQTTAsync.h:1070