简体   繁体   中英

Is there a way to send messages to MQTT mosquitto broker when a database change happens?

I am working on a project which is eventually going to be a website displaying device data with the option to control these devices. I am currently working on the code in python using Paho MQTT Python library. I successfully managed to send and receieve ecrypted messages via mosquitto broker. I have created a client which is a sort of monitoring client that subscribes to a wildcard topic in order to receieve all messages going through the broker and is eventually going to store them into a database. I am using django 2.1.5, mosquitto broker 1.5, working in python.

The problem I am facing right now is that I can't figure out a way to send messages to the mosquitto broker as soon as a database change happens. Let's say I have a website that shows all connected devices and I want to turn one off, I'd click a button, that would change a database table, then a message has to be send to the broker to notify the device that it should switch off. I know I can make the website a client, which would then use MQTT over websockets but that is not a desirable option.

I tried django signals, which seems to work fine. The problem is that the function that the django signal triggers creates a new instance of a new mqtt client. I would like the already running monitoring client to send the message, that is trigger one of its defined functions which would send the message whenever a signal is sent.

class Post(models.Model):
    title = models.CharField(max_length=50)
    def __str__(self):
        return self.title

def save_post(sender, instance, **kwargs):
    message = {
        "client_id": "abc",
        "message": "Created new model: " + str(instance),
    }
     publish.single("house/StateServer/receive", 
         payload=json.dumps(message), 
         port=8081, hostname="localhost", retain=False, 
         auth = {'username':"abc", 'password':"abc"}, 
         client_id="abc",tls = {"ca_certs":"","certfile":"","keyfile":"",})


post_save.connect(save_post, sender=Post)

I would like the "save_post" function to trigger a function of the monitoring client that is running 24/7 and is stored in a different file, let's say "monitor.py". This function of the monitoring client would receieve the desired data: the payload of the message and the topic of the end device, and send it to the mosquitto broker.

I recently had to do something similar from a django post_save. In my case, the equivalent "different file monitor.py" running as a different process launches a thread running a simple SimpleHTTPServer which does all the work of publishing. This allows you to do things asynchrounosly as well since your SimpleHTTPServer could add the received data to be published to a queue and let another thread handle the publish part while your POST handler returns right away.

For reference there is an SO about json and simplehttpserver here: Reading JSON from SimpleHTTPServer Post data

Yes you can do it in post_save signal See this answer . But I would recommend doing in a thread and you can keep qos=2 for delivery but it wont guarantee in case you want the acknowledgement publish back from receiver

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM