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)
Publishing a Time Stamp
Although you can simply publish a single value it may also be useful to publish a time stamp with the value.
In general publishing a time stamp with a retained messages can be useful for the receiver of that message as they will know how old it is and also for any tools that clean out retained messages as they can be set to clear only retained messages that are older than x.
Publishing The IP address of the Client
It may also be useful to publish the IP address of the client as part of the data and perhaps even the client name.
Using JSON Data
If you do decide to publish additional data as part of the connection status then you will need to use JSON data.
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
- Introduction to MQTT +Sparkplug For IIOT
this is very helpful. I was wondering how one could know when a client has disconnected. I could easily add to the payload time() upon connecting, but it wouldn’t work for the last will, unless we update it once in a while, if I understand properly… There is no way to get when a message was published (or triggered, in the case of a last will), am I correct?
You will know when the client got disconnected when you receive the last will message. If a client disconnects normally then they update the connection status before disconnecting.
Does that make sense?
Yeah. Makes sense. If the client interested in knowing that is not on when the other client disconnects then this information is lost. It’s not too bad, anyway. Thanks.
hello sir i am trying to use the same functionality to check weather a device is connected or not. But i am unable to use the will_set function and i am not able to detect the fault over the mqtt network. It is still showing me the connected devices. So can you please help me with this. It will be great help.
Thanks in advance
Can you use the ask steve page and explain how you are doing it and what script you are using
Steve, I found a useful Java based MQTT client which gives a window on the running of the broker – I find it useful – its called MQTT.fx, with it you can connect to the server and either subscribe to any topic or look at the broker status – I find it very useful when one of my little apps decides to drop the connection – so your restart code is going to be helpful!.