英文:
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
答案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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。



评论