The main component of the Paho Python MQTT client library is the client class.
The class provides all the necessary functions to connect to an MQTT broker, publish messages, subscribe to topics and receive messages.
To use you will need to create a new client object from the client class.
The client constructor takes 4 optional parameters. The default values are shown below:
To create a new client object you first need to import the Paho MQTT client, and then create the object as shown below:
client1 = mqtt.Client()
The Client name
Although the client name is optional, it is only optional if clean sessions. are True (default).
However even if you don’t provide a client name one is created for you by the client software.
The screen shot below is taken from the MQTT broker console and shows the result of the client connecting first without specifying a client id and then secondly supplying a client id.
In both case the broker sees a client id as the client will auto generate a random one.
The client name is used by the MQTT broker to identify the client.
This is necessary when using persistent connections as the broker needs to store messages for the client when the client isn’t connected.
Duplicate Client ids
If a client connects with a client id that is in use, and also currently connected then the existing connection is closed.
Because the MQTT client may attempt to reconnect following a disconnect this can result in a loop of disconnect and connect.
The screen shots below show what happens when I try and connect a client (client2) to the broker using the same id as an existing client (client1).
Here is the view from the broker:
In the above you can clearly see that when client 2 connects client 1 gets disconnected. Client 1 then attempts a reconnect which in turn disconnects client 2.
Therefore be careful when assigning client IDs.
Creating Unique Client ids
To create a unique client id you can use one of these popular schemes.
- Client prefix + Serial number of device
- Client prefix + Random Number
- Client prefix + Time
- Client prefix + time+random number
Example Prefix + random number – Myclient-902314
Note: Use of a client prefix is recommended as brokers can filter based on a client-id prefix.
Clean Session Flag
This flag tells the broker to either
- Remember subscriptions and Store messages that the client has missed because it was offline value =False or
- Not to Remember subscriptions and not to Store messages that the client has missed because it was offline – value =True
By default it is set to True
See persistent connections by example to see how persistent connections and clean sessions work.
Clean Sessions and Client Id
With persistent connections the connection details are stored against the client id and so when using persistent connections (clean session False) you cannot use a random client Id.
The user data and protocol parameters are discussed here and I wont discuss them here as the defaults are normally used.
Auxiliary Functions or Settings
There are several Client settings that may need to be changed before a connection is created.
These settings are changed using auxiliary functions. Here is a list of the functions that are available:
- max_inflight_messages_set() –Affects Message throughput
- max_queued_messages_set() –Affects Message throughput
- message_retry_set(retry) –Affects Message throughput
- tls_set() – Used for SSL security
- tls_insecure_set(value) –Used for SSL security
- username_pw_set() – Used for username and passwords
- will_set() –Used for setting last will and testament
The most common used ones are username_pw_set() ,tls_set(),and will_set().
See the Documentation for details
websocket support is also built into the Paho MQTT client.
To Use Websockets with Python. Create the client object using the transport=websockets argument.
See Introduction to MQTT over WebSockets
Simple Client Object Modifications I Make
Important- See note below
I usually add additional flags to the Client object and use them for detecting successful connections and subscribes.
This I do before I create the client object. So often in my test scripts you will see an initialise client object function that looks like this.
def Initialise_client_object(): #flags set mqtt.Client.bad_connection_flag=False mqtt.Client.connected_flag=False mqtt.Client.disconnected_flag=False mqtt.Client.suback_flag=False
Note: I don’t use the above any more as you cannot add lists using this method as they can then be changed by any object instance.
Instead I either create the flags as part of the client instance or I sub class the client object.
So I use either
import paho.mqtt.client as mqtt def Initialise_clients(cname): #callback assignment client= mqtt.Client(cname,False) #don't use clean session if mqttclient_log: #enable mqqt client logging client.on_log=on_log client.on_connect= on_connect #attach function to callback client.on_message=on_message #attach function to callback client.on_subscribe=on_subscribe #flags set client.topic_ack= client.run_flag=False client.running_loop=False client.subscribe_flag=False client.bad_connection_flag=False client.connected_flag=False client.disconnect_flag=False return client
or creating a sub class
import paho.mqtt.client as mqtt class MQTTClient(mqtt.Client): def __init__(self,cname,**kwargs): super(MQTTClient, self).__init__(cname,**kwargs) self.last_pub_time=time.time() self.topic_ack= self.run_flag=True self.subscribe_flag=False self.bad_connection_flag=False self.connected_flag=True self.disconnect_flag=False self.disconnect_time=0.0 self.pub_msg_count=0 self.devices=
Common Questions and Answers
Q- Can two clients have the same client ID?
A- No. If a client connects with a client id that is also currently connected then the existing connection is closed.
Once you have a client object you can connect to the broker —> Client Connections
- Introduction to the Paho Python MQTT Client
- Introduction to the Client Class
- Connecting to a Broker
- Publishing Using The Paho Python MQTT Client
- –Subscribing using The Paho Python Client
- Receiving Messages with the Paho MQTT Python Client
- Understanding The Loop
- Understanding Callbacks
- Handling Multiple Client Connections
We are facing a weird issue while using paho-mqtt client to subscribe to set of topics on mosquitto-broker.
We have published like 30K messages using python-paho-mqtt-client. Publish client says all are sent.
We have subscriber to read all these, client could able to read only portion of the messages, 20k were received and all of a sudden connection dropped saying protocol-error. As we are using loop_forever(), client reconnected but we lost 10k previous messages.
Just wondering why connection dropped after receiving 20k messages?
Hope using clean-session with QOS>1 might help client-reconnection. But why connection is getting dropped in between automatically. Any advice will be much apprecited.
That shouldn’t happen. Can you send me more details on the configuration using the ask steve page. One quick thing to try is to increase the keep alive interval to say 1 hour and opposed to the default of 60 secs.
Nice tutorial! I have benefited a lot from you
You assign the callback function in “Initialise_clients”. However, you wouldn’t do this in a subclass
Is there any reason?
when should I use subclass instead of “Initialise_clients”
It is really a question of preference. Because they are demo scripts I try to keep the code as close to what you would find with the official client.
Your content has been a blessing for me. Thank you so much for putting this up.
Is there a way I can retrieve a client with the client_id? I am working on a project where you can connect and disconnect the client from a webpage. As a result, I am sending an HTTP request that launches the client at the backend but for any other action such as subscribing or publishing, how do I retrieve the launched client? Is it even possible?
Appreciate your help.
Not quite sure of what you are trying to do can you give me more detail. Probably better to use the ask-steve page and then we can use email
Why renew subscription is not working for message_callback_add . clean_session = False .How can i add qos=1 for message_callback_add. Help me to sort out this.
You normally add the subscription in the on_connect callback so it is executed if the client recommects. the code is
where house/bulb = the topic and 1 is the qos
Your Content is Fantastic ,and i thank you for giving this much of worthy content to the world.
**Ques 1:** I run a local mosquitto broker and client .In client side i set clean_season = False and subscribed with qos=1. if client automatically reconnects use of loop_forever() , the subscriptions are renewed automatically and i got message even after client reconnection. But when the Client automatic reconnection due to Duplicate client the subscriptions are not renewed. Should i move client.subscribe into on_connect function or how should i solve this problem. (I am using loop_ forever() for automatic reconnection. )
**Ques 2:** i read your mulitiple client handling posts now what are the parameter should i config to my broker if i 100k users are scaling to use my mosquitto broker.Suggest me best parameters
Because you are using the duplicate client id the client clears the subscribe from the other client. Change client ids and it will solve your problem
Good write up that simplifies the python use of the PAHO library. I was having the issue where my client kept connecting then disconnecting and I could not figure out what was going on then your write up explained that you cannot have two client with the same client IDs. That was my issue so problem solved. Thanks.
The other issue I am having is trying to support in a single configuration the setup of the connection details for connecting using 1883 (MQTT), 8883 (MQTT-TLS) and 443(WSS) to different MQTT hosts. Have all working if a restart my app for testing each, however when I have been connected to a host using a config and I try to change. I get an error trying to call tls_set() a second time. I cannot figure out how to reset once I disconnect from a MQTT host by using different configuration. Example: I was using 8883 with TLS certificates, then disconnect and want to reconnect to another host using credentials on 443 (WSS). I get the message that TLS was already setup when I call tls_set() again.
I don’t want to have the user to close and reopen the app to change connections. Any help would be appreciated.
You need to create a new client object as the old details are still there if you try to reuse the old one you can kep the same names.
Thanks ever so much for all this Steve.
I clearly have much to learn regarding Python but where I did get a bit lost was in your section “The Client name” and working out the distinction between “client name” and “client id”. Seems to me at the moment that they are same thing but I have a lot to grasp on this subject as yet although I have managed to get a temperature sensor up & running
Yes you are correct they are the same thing.