This tutorial is in response to a question I received on the client connections tutorial page:
I’ve been struggling to find a real client connection status tool, dashboard or anything which will show a list of my clients and their connection status. Clearly the broker via the low-level protocol mechanics maintain an MQTT keepalive table for each client — that’s how Last Will and Testament (LWT) is triggered internally by the broker. However how does one display such table?
The problem is that you have no way of accessing the connections table on the broker so the only way is to build the functionality into the clients.
- Publish it’s current connection status to an agreed on topic.
- Publish a last will message on the connection status topic to indicate failure.
- Publish a not connected message before disconnecting.
The connection scanner is a simple client application that subscribes to the connection status topic and maintains a list of connected clients.
Connection Status Topic
Currently there is no standard topic structure or naming convention but with public MQTT deployments then this will become necessary. See MQTT topic Payload design notes.
Note: Also see this github proposal which I used as the basis for this design.
There are various choices.We can:
- Use a system wide topic
- Use a group topic.
System wide topic
Similar to the $SYS topic structure
Where $CONNECTED is the root topic.
The sensor status would be part of the payload.We could use:
- 0- Not Connected
- 1 – Connected
Group Wide Topic
Sensors publish on root topic sensors using the forms:
- sensors/status/sensorname or
and subscribe for control message on
- sensors/control/sensorname or
Sensors could publish the connection status to:
- sensors/connected/sensorname or
Status Payload Messages are as above.
Note: Using a $ to denote special topics is becoming a kind of standard and so you could use $control, $status and $connected.
Implementation Using Python
It can easily be added to existing code in the on_connect callback. Here is my code with the addition.
def on_connect(client, userdata, flags, rc): logging.debug("Connected flags"+str(flags)+"result code "\ +str(rc)+"client1_id") if rc==0: client.connected_flag=True client.publish(connection_topic,1,retain=True) else: client.bad_connection_flag=True
We also need to Set the last will message.Payload is 0 and we use the retain flag.
client.will_set(connected_topic,0, qos=0, retain=True) #set will
The last will will take care of an abnormal disconnect. For a normal disconnect we need to remember to update the status before we disconnect as follows:
Rather than writing a Python script to scan the topics I will use the mosquitto_sub client tool.
We subscribe to sensors/connected/# as shown below:
Now we start the sensors. sensor1 and sensor2
Now Check the status using the scanner we should see the connection status has been updated and they are both connected.
Now Stop sensor2 using CTRL+C to simulate a network fault.
Recheck the connection status, and we should see the connection status of sensor2 has changed to not connected. (0)
The script used in this tutorial :
- Using The Mosquitto_pub and Mosquitto_sub MQTT Client Tools- Examples
- MQTT Retained Messages Explained
- MQTT Last Will and Testament Examples
- Understanding MQTT Topic Naming and Design Notes