Search code examples
pythoncallbackmqttglobalpaho

How do I avoid global variables when using MQTT callbacks


I am incrementing a global variable in my on_receive callback, to track how many messages have been received. I need to know this count for testing purposes.

Since global variables are generally considered a code smell, is there a way to avoid using global variables in this situation?

Here is my callback:

def on_message_callback_v3( message_client, userdata, message ):
  global global_message_received_count
  with my_mutex:
    global_message_received_count += 1
    msg = str( message.payload.decode( "utf-8" ) )
    print( f"▼▼ ON MESSAGE ▼▼" )
    print( f"  Message received for client: {message_client}" )
    print( f"  Message user data: {userdata}" )
    print( f"  Message topic: {message.topic}" )
    print( f"  Message body: {msg}" )

When all messages have been published, I compare global_message_received_count to the published_count (incremented elsewhere), to determine if all messages have been received. Since the signature of the callback is enforced by Paho, I cannot pass in or return variables.

I would like to avoid replying on the global global_message_received_count.


Solution

  • My solution would be to use a class / object that handles receiving messages. That way, the count can be a property of the handler object (code simplified):

    class MessageReceivedHandler:
        count = 0
          
        def on_message_callback(self, message_client, userdata, message):
            self.count += 1
            print(message)
    

    You can then create an instance of the handler: handler = MessageReceivedHandler() and pass handler.on_message_callback as the callback. The handler.count variable can then be accessed to check the amount of received messages.