I am trying to implement Paho MQTT on Django but Django stops receiving/sending MQTT messages after raising any kind of exception.
I am using Paho MQTT client 1.3.0 along with Django 1.10.8, Python 3.6.2
Here are my MQTT settings:
mqtt.py
from django.conf import settings
import paho.mqtt.client as mqtt
SUB_TOPICS = ("device/vlt", "device/auth", "device/cfg", "device/hlt", "device/etracker", "device/pi")
RECONNECT_DELAY_SECS = 2
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
print("Connected with result code " + str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
for topic in SUB_TOPICS:
client.subscribe(topic, qos=0)
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
def on_publish(mosq, obj, mid):
print("mid: " + str(mid))
def on_subscribe(mosq, obj, mid, granted_qos):
print("Subscribed: " + str(mid) + " " + str(granted_qos))
def on_log(mosq, obj, level, string):
print(string)
def on_disconnect(client, userdata, rc):
client.loop_stop(force=False)
if rc != 0:
print("Unexpected disconnection: rc:" + str(rc))
else:
print("Disconnected: rc:" + str(rc))
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
client.on_publish = on_publish
client.on_subscribe = on_subscribe
client.on_disconnect = on_disconnect
client.username_pw_set(username, password)
client.connect(<settings>)
apps.py
class CoreConfig(AppConfig):
name = 'untitled.core'
verbose_name = "Core"
def ready(self):
from . import mqtt
mqtt.client.loop_start()
Code inspiration: Paho MQTT client connection reliability (reconnect on disconnection)
My team happen to face this problem as well and we solve it by creating a CustomMqttClient that inherit from mqtt.Client and override the _handle_on_message(self, message) function.
class CustomMqttClient(mqtt.Client):
def _handle_on_message(self, message):
try:
super(ChatqMqttClient, self)._handle_on_message(message)
except Exception as e:
error = {"exception": str(e.__class__.__name__), "message": str(e)}
self.publish("device/exception", json.dumps(error))
Then instead of using mqtt.Client(), we do this:
client = CustomMqttClient()
client.on_connect = on_connect
client.on_message = on_message
This catches all exception and actually publish it to our topic device/exception. Our other services can actually subscribe to it and actually get some useful information out of it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With