Django中继承类时避免每次MQTT消息发布都执行父类初始化的方案咨询
解决方案
问题根因
你当前将client.connect、client.loop_start等长生命周期的连接逻辑放在了父类Initializer的构造方法__init__中,每次实例化PublishData子类时都会触发父类构造方法执行连接逻辑。如果你的业务代码中每次发布消息都新建一个PublishData实例,自然会重复执行连接、启动循环的逻辑。
另外注意你现有代码存在类名大小写不统一的问题:定义的类名是publishdata,实例化时写的是PublishData,实际运行会报错,需要先修正。
优化方案
方案1:单例模式复用连接实例
保证全局只有一个MQTT客户端实例,只会执行一次连接、启动循环的逻辑:
import mqtt import time # 父类实现单例逻辑 class Initializer(): # 保存单例实例 _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super().__new__(cls, *args, **kwargs) # 连接逻辑只在第一次创建实例时执行 cls._instance.client = mqtt.Client(mqtt_server+str(int(time.time()))) cls._instance.client.username_pw_set(username=mqtt_username, password=mqtt_password) cls._instance.client.on_connect = cls._instance.on_connect cls._instance.client.subscribe("topic") cls._instance.client.connect(broker, mqtt_port) cls._instance.client.loop_start() return cls._instance def on_connect(self, client, userdata, flags, rc): # 你自己的连接回调逻辑 pass class PublishData(Initializer): def __init__(self): # 单例模式下__init__可能会多次执行,回调只需要赋值一次,加判断避免重复赋值 if not hasattr(self, 'callback_inited'): self.client.on_message = self.on_message self.client.on_subscribe = self.on_subscribe self.callback_inited = True def on_subscribe(self, client, userdata, mid, granted_qos): print("Subscription started") def on_message(self, client, userdata, message): print(message.topic, message.payload) def begin(self,topic,data): self.client.publish(topic, str(data)) # 无论实例化多少次,都只会用同一个连接 publishData1 = PublishData() publishData1.begin(topic1, data1) publishData2 = PublishData() publishData2.begin(topic2, data2) # 上述两次实例化、两次发布,只会执行一次连接逻辑
方案2:显式初始化连接,全局复用实例
如果可以控制实例化时机,直接提前初始化一次实例,后续所有发布操作都复用同一个实例即可,不需要修改父类原有逻辑:
# 程序启动/业务模块初始化时,只实例化一次 global_publish_client = PublishData() # 所有需要发消息的地方,都直接复用这个实例 global_publish_client.begin(topic, data)
额外建议
- 如果你的程序只有MQTT发布需求,不需要订阅,可以把订阅逻辑从初始化类中拆分出来,减少不必要的资源消耗
- 可以增加连接状态判断,发布前如果检测到连接断开,自动重连,避免发布失败
内容的提问来源于stack exchange,提问作者Aneesh
相关产品推荐
相关产品推荐

