Paho Python MQTT client connects successfully but on_connect callback is not invoked

14,428

Solution 1

The reason this isn't working is that you aren't calling any of the loop*() functions. These process network traffic. If you don't use one, there is no guarantee your outgoing messages will be sent and absolutely no incoming messages will be processed.

loop_forever() is a blocking call that processes the network loop - probably not what you want.

loop_start() starts a thread to process the network loop and so returns straight away.

I would do this:

mqttc.connect(broker, broker_port, 60) # Don't forget to handle errors
mqttc.loop_start()

while 1:
    try:
        topic = "this/is/a/test/topic"
        payload = "test_message"
        print "Publishing " + payload + " to topic: " + topic + " ..."
        mqttc.publish(topic, payload, 0)

    except Exception as e:
        print "exception"
        log_file=open("log.txt","w")
        log_file.write(str(time.time())+" "+e.__str__())
        log_file.close()

    print ""
    time.sleep(3)

You do still need to fix your on_connect callback as @Kiran says.

There is no need to disconnect each time - and in fact there is no guarantee your message will have been sent when you do disconnect. You should use the on_publish callback to know when the message is sent.

If you want to do a simple connect-publish-disconnect, then maybe use the paho.mqtt.publish helper module:

import paho.mqtt.publish as publish

while 1:
    try:
        topic = "this/is/a/test/topic"
        payload = "test_message"
        print "Publishing " + payload + " to topic: " + topic + " ..."
        publish.single(topic, payload, 0, host=broker, port=broker_port)

    except Exception as e:
        print "exception"
        log_file=open("log.txt","w")
        log_file.write(str(time.time())+" "+e.__str__())
        log_file.close()

    print ""
    time.sleep(3)

Solution 2

Your on_connect() method declaration is missing the flags(1) parameter. So it is not getting invoked. Flags parameter contained the response sent by broker. It had to be

def on_connect(mqttc, userdata, flags, rc):

Also, why are you connecting and disconnecting in loop ? Try using the loop_start() and loop_stop() methods which handles auto-reconnections on a connection drop(example).

Share:
14,428
evgi9
Author by

evgi9

Updated on July 24, 2022

Comments

  • evgi9
    evgi9 almost 2 years

    I have a simple script on a Raspberry Pi that publishes a sample message every 3 seconds. I have declared the callbacks on_connect, on_publish and on_disconnect. This client connects successfully but on_connect is not called, publishes and on_publish is called, disconnects and on_disconnect is called.

    This is my script

    import paho.mqtt.client as mqtt
    import time
    
    def on_connect(mqttc, userdata, rc):
        print("Connected with result code "+str(rc))
        if rc!=0 :
            mqttc.reconnect()
    
    def on_publish(mqttc, userdata, mid):
        print "Published"
    
    def on_disconnect(mqttc, userdata, rc):
        if rc != 0:
            print("Unexpected disconnection. Reconnecting...")
            mqttc.reconnect()
        else :
            print "Disconnected successfully"
    
    # Setup MQTT
    # broker='test.mosquitto.org'
    broker = 'iot.eclipse.org'
    broker_port=1883
    
    # Create a client instance
    mqttc=mqtt.Client(client_id="MyClient")
    mqttc.on_connect = on_connect
    mqttc.on_publish = on_publish
    mqttc.on_disconnect = on_disconnect
    
    while 1:
    
        mqttc.connect(broker, broker_port, 60)
        # print "Connected."    # I don't want this message. 
                                # Why isn't the on_connect callback invoked?
    
        try:
            topic = "this/is/a/test/topic"
            payload = "test_message"
            print "Publishing " + payload + " to topic: " + topic + " ..."
            mqttc.publish(topic, payload, 0)
    
        except Exception as e:
            print "exception"
            log_file=open("log.txt","w")
            log_file.write(str(time.time())+" "+e.__str__())
            log_file.close()
    
        mqttc.disconnect()
        print ""
        time.sleep(3)   
    

    Although this minor "bug" doesn't affect the message publishing, which is mainly what I want to achieve, why does it happen and how can I resolve it?

  • evgi9
    evgi9 about 8 years
    The broker that I am currently using (not the one in the example) can handle a maximum number of clients connected to it. Since there are more clients that send data periodically, the logic behind connect-send-disconnect is to allow more of them connected to the broker.
  • kiranpradeep
    kiranpradeep about 8 years
    @evgi9 For that, you can also use global helper functions(1)
  • GeneCode
    GeneCode over 3 years
    Adding loopstart after connect works for me. Thanks bruh