feat:初始化工程
This commit is contained in:
136
endpoint/mqtt_client.py
Normal file
136
endpoint/mqtt_client.py
Normal file
@@ -0,0 +1,136 @@
|
||||
import paho.mqtt.client as mqtt
|
||||
import uuid
|
||||
from config.logger_config import logger
|
||||
from config.setting import settings
|
||||
|
||||
|
||||
class MQTTClient:
|
||||
def __init__(self):
|
||||
self.broker_host = settings.mqtt_host
|
||||
self.broker_port = settings.mqtt_port
|
||||
self.client_id = self.generate_client_id()
|
||||
|
||||
self.client = mqtt.Client(client_id=self.client_id)
|
||||
|
||||
# 注册回调函数
|
||||
self.client.on_connect = self._on_connect
|
||||
self.client.on_disconnect = self._on_disconnect
|
||||
self.client.on_message = self._on_message
|
||||
|
||||
# 存储消息处理器的字典,键为主题,值为处理函数
|
||||
self.message_handlers = {}
|
||||
|
||||
self.connected = False
|
||||
|
||||
def _on_connect(self, client, userdata, flags, rc):
|
||||
"""连接回调函数"""
|
||||
self.connected = rc == 0
|
||||
if self.connected:
|
||||
logger.info(f"成功连接到MQTT broker {self.broker_host}:{self.broker_port}")
|
||||
else:
|
||||
logger.error(f"连接MQTT broker失败,错误代码: {rc}")
|
||||
|
||||
def _on_disconnect(self, client, userdata, rc):
|
||||
"""断开连接回调函数"""
|
||||
self.connected = False
|
||||
if rc != 0:
|
||||
logger.warning(f"意外断开与MQTT broker的连接,错误代码: {rc}")
|
||||
else:
|
||||
logger.info("已与MQTT broker断开连接")
|
||||
|
||||
def _on_message(self, client, userdata, msg):
|
||||
"""消息接收回调函数"""
|
||||
logger.info(f"收到消息: {msg.topic}")
|
||||
try:
|
||||
if msg.topic in self.message_handlers:
|
||||
self.message_handlers[msg.topic](client, msg)
|
||||
else:
|
||||
logger.warning(f"未找到 {msg.topic} 的消息处理器")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"处理消息时出错: {str(e)}", exc_info=True)
|
||||
|
||||
@staticmethod
|
||||
def generate_client_id(prefix: str = "client") -> str:
|
||||
"""生成唯一客户端ID"""
|
||||
uuid_str = str(uuid.uuid4()).split('-')[0]
|
||||
return f"{prefix}-{uuid_str}"
|
||||
|
||||
def add_message_handler(self, topic, handler):
|
||||
"""添加消息处理器"""
|
||||
if topic in self.message_handlers:
|
||||
logger.warning(f"主题 {topic} 已存在处理器,将被覆盖")
|
||||
self.message_handlers[topic] = handler
|
||||
logger.info(f"为主题 {topic} 注册了消息处理器")
|
||||
logger.debug(f"当前消息处理器: {self.message_handlers.keys()}")
|
||||
|
||||
def connect(self):
|
||||
"""连接到MQTT服务器"""
|
||||
try:
|
||||
self.client.connect(self.broker_host, self.broker_port)
|
||||
self.start_loop()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"连接MQTT broker {self.broker_host}:{self.broker_port}时发生错误: {str(e)}", exc_info=True)
|
||||
return False
|
||||
|
||||
def disconnect(self):
|
||||
"""断开与MQTT服务器的连接"""
|
||||
try:
|
||||
self.stop_loop()
|
||||
self.client.disconnect()
|
||||
logger.info("正在断开与MQTT broker的连接")
|
||||
except Exception as e:
|
||||
logger.error(f"断开连接时发生错误: {str(e)}", exc_info=True)
|
||||
|
||||
def subscribe(self, topic, qos=0):
|
||||
"""订阅主题"""
|
||||
try:
|
||||
result, mid = self.client.subscribe(topic, qos)
|
||||
if result == mqtt.MQTT_ERR_SUCCESS:
|
||||
logger.info(f"已订阅主题: {topic} (QoS: {qos})")
|
||||
return True
|
||||
else:
|
||||
logger.error(f"订阅主题 {topic} 失败,错误代码: {result}")
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.error(f"订阅主题时发生错误: {str(e)}", exc_info=True)
|
||||
return False
|
||||
|
||||
def publish(self, topic, payload, qos=0, retain=False):
|
||||
"""发布消息到指定主题"""
|
||||
if not self.connected:
|
||||
logger.warning("未连接到MQTT broker,无法发布消息")
|
||||
return False
|
||||
|
||||
try:
|
||||
result = self.client.publish(topic, payload, qos, retain)
|
||||
result.wait_for_publish()
|
||||
if result.rc == mqtt.MQTT_ERR_SUCCESS:
|
||||
logger.debug(f"已发布消息到主题 {topic}: {payload}")
|
||||
return True
|
||||
else:
|
||||
logger.error(f"发布消息到主题 {topic} 失败,错误代码: {result.rc}")
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.error(f"发布消息时发生错误: {str(e)}", exc_info=True)
|
||||
return False
|
||||
|
||||
def start_loop(self):
|
||||
"""启动MQTT网络循环"""
|
||||
try:
|
||||
self.client.loop_start()
|
||||
logger.info("已启动MQTT网络循环")
|
||||
except Exception as e:
|
||||
logger.error(f"启动网络循环时发生错误: {str(e)}", exc_info=True)
|
||||
|
||||
def stop_loop(self):
|
||||
"""停止MQTT网络循环"""
|
||||
try:
|
||||
self.client.loop_stop()
|
||||
logger.info("已停止MQTT网络循环")
|
||||
except Exception as e:
|
||||
logger.error(f"停止网络循环时发生错误: {str(e)}", exc_info=True)
|
||||
|
||||
|
||||
mqtt_client = MQTTClient()
|
||||
Reference in New Issue
Block a user