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

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

Django Python MQTT Subscribe onMessage got executed two times

问题

以下是翻译的代码部分:

  1. 我有我的Mosquitto MQTT代理我创建了一个简单的Django应用程序订阅主题`$SYS/broker/uptime`如下所示
  2. from django.apps import AppConfig
  3. from threading import Thread
  4. import paho.mqtt.client as mqtt
  5. class MqttClient(Thread):
  6. def __init__(self, broker, port, timeout, topics):
  7. super(MqttClient, self).__init__()
  8. self.client = mqtt.Client()
  9. self.broker = broker
  10. self.port = port
  11. self.timeout = timeout
  12. self.topics = topics
  13. self.total_messages = 0
  14. # run方法覆盖自Thread类
  15. def run(self):
  16. self.connect_to_broker()
  17. def connect_to_broker(self):
  18. self.client.on_connect = self.on_connect
  19. self.client.on_message = self.on_message
  20. self.client.connect(self.broker, self.port, self.timeout)
  21. self.client.loop_forever()
  22. # 当从服务器接收到PUBLISH消息时的回调
  23. def on_message(self, client, userdata, msg):
  24. self.total_messages = self.total_messages + 1
  25. print(str(msg.payload) + "Total: {}".format(self.total_messages))
  26. # 当客户端从服务器接收到CONNACK响应时的回调
  27. def on_connect(self, client, userdata, flags, rc):
  28. # 使用锁定订阅主题的方式订阅主题的列表,以确保每个主题只订阅一次
  29. for topic in self.topics:
  30. client.subscribe(topic)
  31. class AppMqtteConfig(AppConfig):
  32. default_auto_field = 'django.db.models.BigAutoField'
  33. name = 'app_mqtt'
  34. def ready(self):
  35. 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

  1. from django.apps import AppConfig
  2. from threading import Thread
  3. import paho.mqtt.client as mqtt
  4. class MqttClient(Thread):
  5. def __init__(self, broker, port, timeout, topics):
  6. super(MqttClient, self).__init__()
  7. self.client = mqtt.Client()
  8. self.broker = broker
  9. self.port = port
  10. self.timeout = timeout
  11. self.topics = topics
  12. self.total_messages = 0
  13. # run method override from Thread class
  14. def run(self):
  15. self.connect_to_broker()
  16. def connect_to_broker(self):
  17. self.client.on_connect = self.on_connect
  18. self.client.on_message = self.on_message
  19. self.client.connect(self.broker, self.port, self.timeout)
  20. self.client.loop_forever()
  21. # The callback for when a PUBLISH message is received from the server.
  22. def on_message(self, client, userdata, msg):
  23. self.total_messages = self.total_messages + 1
  24. print(str(msg.payload) + "Total: {}".format(self.total_messages))
  25. # The callback for when the client receives a CONNACK response from the server.
  26. def on_connect(self, client, userdata, flags, rc):
  27. # Subscribe to a list of topics using a lock to guarantee that a topic is only subscribed once
  28. for topic in self.topics:
  29. client.subscribe(topic)
  30. class AppMqtteConfig(AppConfig):
  31. default_auto_field = 'django.db.models.BigAutoField'
  32. name = 'app_mqtt'
  33. def ready(self):
  34. 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:

确定