I'm using Mosquitto and the Python implementation of Paho to try to communicate a couple of programmes. I'm getting some troubles when I use the last will function. My code is this:
Suscriber:
import paho.mqtt.client as mqtt
def on_message(client, userdata, msg):
print 'Received: ' + msg.payload
client = mqtt.Client()
client.on_message = on_message
client.connect('localhost', 1883)
client.subscribe('hello/#')
client.loop_forever()
Publisher:
import paho.mqtt.client as mqtt
client = mqtt.Client()
client.will_set('hello/will', 'Last will', 0, False)
client.connect('localhost', 1883)
client.publish('hello/world', 'Regular msg', 0, False)
client.disconnect()
The output:
Received: Last will
I should receive only the regular message because I use client.disconnect()
to close the connection. If I comment the will_set
line, I get the regular message. I also tried publishing both on the same topic and it doesn't work.
The Last will and testament feature requires to follow some rules.
client.will_set
before you connectPut call to will_set
before client.connect
.
client = mqtt.Client()
client.will_set("stack/clientstatus", "LOST_CONNECTION", 0, False)
client.connect(host, port, timeout)
Calling will_set
after connect did not work for me.
client.will_set
countsTrying to use will_set
multiple times is possible, but only the last one will be effective, previous ones will be ignored.
client.disconnect
to completeThe client.disconnect
is actually request to send out the "DISCONNECT" message to the broker.
As the messages are sent asynchronously, it is possible, that your program ends sooner, then is the "DISCONNECT" message completed.
Use client.loop_*()
after client.disconnect
This shall allow the client to complete the process of sending the "DISCONNECT" message out.
Following combinations worked for me:
loop_start()
-> loop_stop()
loop_start()
-> loop_forever()
(it completes after sending DISCONNECT message)I did not experiment with other combinations.
From those option, the first one seems better to me (keeping loop_start
paired with loop_stop
). The second option might be simply wrong.
My working code:
import paho.mqtt.client as mqtt
host = "test.mosquitto.org"
port = 1883
timeout = 10
client = mqtt.Client()
client.will_set("stack/clientstatus", "LOST_CONNECTION", 0, False)
client.connect(host, port, timeout)
client.publish("stack/clientstatus", "ON-LINE")
client.loop_start()
for msg in ["msg1", "msg2", "msg3"]:
client.publish("stack/message", msg)
print msg
client.publish("stack/clientstatus", "OFF-LINE")
client.disconnect()
client.loop_stop() # waits, until DISCONNECT message is sent out
print "Now I am done."
sleep
, adding on_disconnect
)Adding time.sleep
might help, but in other situation (not reliable connection) could fail.
Adding client.on_disconnect = on_disconnect
did not help in my case as it seems, this callback is processed asynchronously and does not block the client.disconnect
call.