Django Python MQTT Subscribe onMessage 被执行了两次。

huangapple go评论71阅读模式
英文:

Django Python MQTT Subscribe onMessage got executed two times

问题

以下是翻译的代码部分:

我有我的Mosquitto MQTT代理我创建了一个简单的Django应用程序订阅主题`$SYS/broker/uptime`如下所示

from django.apps import AppConfig
from threading import Thread
import paho.mqtt.client as mqtt


class MqttClient(Thread):
    def __init__(self, broker, port, timeout, topics):
        super(MqttClient, self).__init__()
        self.client = mqtt.Client()
        self.broker = broker
        self.port = port
        self.timeout = timeout
        self.topics = topics
        self.total_messages = 0

    # run方法覆盖自Thread类

    def run(self):
        self.connect_to_broker()

    def connect_to_broker(self):
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        self.client.connect(self.broker, self.port, self.timeout)
        self.client.loop_forever()

    # 当从服务器接收到PUBLISH消息时的回调

    def on_message(self, client, userdata, msg):
        self.total_messages = self.total_messages + 1
        print(str(msg.payload) + "Total: {}".format(self.total_messages))

    # 当客户端从服务器接收到CONNACK响应时的回调

    def on_connect(self, client, userdata, flags, rc):
        # 使用锁定订阅主题的方式订阅主题的列表,以确保每个主题只订阅一次
        for topic in self.topics:
            client.subscribe(topic)


class AppMqtteConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'app_mqtt'

    def ready(self):
        MqttClient("localhost", 1883, 60, ["$SYS/broker/uptime"]).start()

希望这对你有帮助。

英文:

I've my Mosquitto MQTT broker and I've created a simple Django APP that subscribes to the topic $SYS/broker/uptime like below

from django.apps import AppConfig
from threading import Thread
import paho.mqtt.client as mqtt


class MqttClient(Thread):
    def __init__(self, broker, port, timeout, topics):
        super(MqttClient, self).__init__()
        self.client = mqtt.Client()
        self.broker = broker
        self.port = port
        self.timeout = timeout
        self.topics = topics
        self.total_messages = 0

    #  run method override from Thread class

    def run(self):
        self.connect_to_broker()

    def connect_to_broker(self):
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        self.client.connect(self.broker, self.port, self.timeout)
        self.client.loop_forever()

    # The callback for when a PUBLISH message is received from the server.

    def on_message(self, client, userdata, msg):
        self.total_messages = self.total_messages + 1
        print(str(msg.payload) + "Total: {}".format(self.total_messages))


    # The callback for when the client receives a CONNACK response from the server.

    def on_connect(self, client, userdata, flags, rc):
        #  Subscribe to a list of topics using a lock to guarantee that a topic is only subscribed once
        for topic in self.topics:
            client.subscribe(topic)


class AppMqtteConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'app_mqtt'

    def ready(self):
        MqttClient("localhost", 1883, 60, ["$SYS/broker/uptime"]).start()

For some reason, the print statement on the on_message callback got executed two times, at least from what I'm seeing from the console. See screenshot. I can't understand why

Django Python MQTT Subscribe onMessage 被执行了两次。

答案1

得分: 1

在某些情况下,特别是在测试中,可以多次调用ready方法,正如文档中所建议的。

此答案所解释,可以在ready方法之前添加if os.environ.get('RUN_MAIN'):以解决这个问题。

英文:

It turned out that in some instances, particularly in tests, the ready method could be called multiple times as suggested in the Documentation.

As explained on this answer the issue is resolved with an if os.environ.get('RUN_MAIN'): before the ready method

huangapple
  • 本文由 发表于 2023年2月10日 16:34:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75408638.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定