Blog Datasheets Home About me Clients My work Services Contact

G2Labs Grzegorz Grzęda

MQTT Best Practices for Intermediate C and Python Programmers: Tips for Efficient Implementation

September 25, 2023

MQTT Best Practices for Intermediate C and Python Programmers: Tips for Efficient Implementation

Message Queuing Telemetry Transport (MQTT) is a lightweight messaging protocol commonly used in the Internet of Things (IoT) and other applications that require low bandwidth and low latency communication. As an intermediate C and Python programmer, efficiently implementing MQTT can be crucial for developing reliable and scalable applications. In this blog post, we will explore best practices for using MQTT in C and Python, with extensive examples and detailed explanations.

Understanding the Basics of MQTT

Before diving into best practices, it’s important to have a solid understanding of the basic concepts of MQTT. MQTT operates on the publish-subscribe messaging pattern, where clients (publishers) send messages to a broker, and other clients (subscribers) receive the messages from the broker. The key components of MQTT include the broker, topics, and Quality of Service levels (QoS).

Best Practices in C

Using a High-Quality MQTT Client Library

When working with MQTT in C, using a high-quality MQTT client library can greatly simplify the implementation process. One popular choice is the Eclipse Paho MQTT C client, which provides a robust and feature-rich API for interacting with MQTT brokers. Here’s an example of how to publish a message using the Paho MQTT C client:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#include <string.h>
#include <MQTTClient.h>

#define ADDRESS     "tcp://localhost:1883"
#define CLIENTID    "ExampleClientPub"
#define TOPIC       "sensor/data"
#define QOS         1
#define TIMEOUT     10000L

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

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

    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        return rc;
    }

    pubmsg.payload = "Hello, MQTT";
    pubmsg.payloadlen = strlen(pubmsg.payload);
    pubmsg.qos = QOS;
    pubmsg.retained = 0;
    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), pubmsg.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;
}

Handling Reconnections and Error Scenarios

In real-world scenarios, network or broker disruptions can occur, leading to connection drops. It’s important to implement reconnection logic and handle error scenarios gracefully. Here’s an example of how to implement reconnect logic in the Paho MQTT C client:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
void on_connection_lost(void *context, char *cause)
{
    printf("\nConnection lost\n");
    printf("   cause: %s\n", cause);
}

void on_delivery_complete(void *context, MQTTClient_deliveryToken token)
{
    printf("Delivery complete\n");
}

MQTTClient_setCallbacks(client, NULL, on_connection_lost, on_message_arrived, on_delivery_complete);

// Implement reconnect logic
while ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
    printf("Failed to connect, return code %d\n", rc);
}

Best Practices in Python

Utilizing the Paho MQTT Python Client

For Python developers, the Paho MQTT Python client provides a convenient and powerful way to interact with MQTT brokers. Here’s an example of how to publish a message using the Paho MQTT Python client:

1
2
3
4
5
6
7
8
9
import paho.mqtt.client as mqtt

broker_address = "localhost"
client = mqtt.Client("P1")
client.connect(broker_address)

topic = "sensor/data"
message = "Hello, MQTT"
client.publish(topic, message)

Properly Managing Client Callbacks

Handling client callbacks correctly is vital when working with the Paho MQTT Python client. By properly setting up callback functions for events such as connection loss, message arrival, and delivery completion, you can ensure robust and reliable communication with the MQTT broker.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
def on_connect(client, userdata, flags, rc):
    print("Connected with result code " + str(rc))

def on_message(client, userdata, msg):
    print(msg.topic + " " + str(msg.payload))

def on_disconnect(client, userdata, rc):
    print("Disconnected with result code " + str(rc))

client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect

Conclusion

In this blog post, we’ve covered best practices for efficiently implementing MQTT in C and Python for intermediate programmers. By utilizing high-quality MQTT client libraries, handling reconnections and error scenarios, and properly managing client callbacks, you can develop robust and reliable MQTT-based applications. Whether you’re working on IoT projects or other messaging applications, mastering these best practices will enable you to create efficient and scalable solutions using MQTT. Happy coding!


➡️ Introduction to the nRF52 microcontroller: features and capabilities


⬅️ Exploring MQTT Message Filtering in C and Python Development: Intermediate Concepts


Go back to Posts.