Checking Active MQTT Client Connections

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.

Client Requirements

  1. Publish it’s current connection status to an agreed on topic.
  2. Publish a last will message on the connection status topic to indicate failure.
  3. Publish a not connected message before disconnecting.

Connection Scanner

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

Use:  $CONNECTED/sensorname

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
  • sensors/sensorname/status

and subscribe for control message on

  • sensors/control/sensorname or
  • sensors/sensorname/control

Sensors could publish the connection status to:

  • sensors/connected/sensorname  or
  • sensors/sensorname/connected

Status Payload Messages are as above.

Note 1: Using a $ to denote special topics is becoming a kind of standard and so you could use $control, $status and $connected.

Note2: Sparkplug uses the topic STATE

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:

client.publish(connection_topic,0,retain=True)
client.disconnect()

Testing

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:

connection-status-example1

Now we start the sensors. sensor1 and sensor2

connection-status-example2

Now Check the status using the scanner we should see the connection status has been updated and they are both connected.

connection-status-example3

Now Stop sensor2 using CTRL+C to simulate a network fault.

connection-status-example4.jpg

Recheck the connection status, and we should see the connection status of sensor2 has changed to not connected. (0)

connection-status-example5

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 (secs).

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.


coffeeIf you found this guide useful then perhaps you would like to Buy Me a Coffee

Resources:

The script used in this tutorial :

Related Tutorials

Please rate? And use Comments to let me know more

6 comments

  1. Hi Steve,
    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?

    1. 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?
      Rgds
      Steve

      1. 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.

  2. 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

  3. 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!.

Leave a Reply

Your email address will not be published. Required fields are marked *