import json import logging import paho.mqtt.client as mqtt import threading import queue import time # MQTT 代理地址和端口 broker = "8.137.54.85" # 公共 MQTT 代理(免费) port = 1883 # MQTT 默认端口 # 主题 topic = "ai/tottle/uvmodule" # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) # 创建消息队列 message_queue = queue.Queue() # 全局消息队列(可选,如果多个客户端需要共享消息) global_message_queue = queue.Queue() # uv_message_queue = queue.Queue() # 接收消息并做本地缓存 # message_receive_queue = queue.Queue() # # 暂时考虑只存储最新一条消息 # message_receive_queue = None class MQTTClient: def __init__(self, broker, port, topic, use_global_queue=False): self.broker = broker self.port = port self.topic = topic self.client = mqtt.Client() self.client.on_connect = self.on_connect self.client.on_message = self.on_message # 绑定消息回调 self.use_global_queue = use_global_queue # 是否使用全局队列 self.local_mess = None self.local_message_queue = queue.Queue() if not use_global_queue else None # 本地队列 self.client.connect(broker, port) self.client.loop_start() # 启动网络线程 def on_connect(self, client, userdata, flags, rc): """连接成功时自动订阅主题""" if rc == 0: print(f"[MQTT] 成功连接到代理 {self.broker}:{self.port}") self.client.subscribe(self.topic) else: print(f"[MQTT] 连接失败,错误代码: {rc}") def on_message(self, client, userdata, msg): """收到消息时的回调""" try: payload = msg.payload.decode("utf-8") # message_data = { # "topic": msg.topic, # "payload": payload, # "qos": msg.qos, # "retain": msg.retain, # "ts": int(time.time() * 1000) # 毫秒级时间戳 # } # data = json.loads(payload) # 解析为字典 message_data = json.loads(payload) # 解析为字典 # if self.use_global_queue: # global_message_queue.put(message_data) # 存入全局队列 # else: # self.local_message_queue.put(message_data) # 存入本地队列 print(f"on_message {message_data}") # 增加格式验证,非法格式不做录入 if (message_data is not None and message_data["task_id"] is not None and message_data["list_s3_url"] is not None and message_data["list_func_id"] is not None): #接收ai-tottle 消息 global_message_queue.put(message_data) # 存入全局队列 # self.local_mess=message_data # print(f"[MQTT 接收] 主题: {msg.topic}, 消息: {payload}") except Exception as e: print(f"[MQTT 错误] 消息处理失败: {e}") def publish_message(self, message): """发布消息""" self.client.publish(self.topic, message) print(f"[MQTT 发送] 主题: {self.topic}, 消息: {message}") def publish_uv_result(self,topic, message): """发布消息""" self.client.publish(topic, message) print(f"[MQTT 发送] 主题: {self.topic}, 消息: {message}") def get_messages(self, timeout=1): """ 获取消息(支持超时) - 如果使用全局队列,从 global_message_queue 获取 - 否则从本地队列获取 """ messages = None # target_queue = global_message_queue if self.use_global_queue else self.local_message_queue start_time = time.time() while time.time() - start_time < timeout: try: msg = global_message_queue.get() if msg: messages =msg except queue.Empty: break return messages def close(self): """关闭连接""" self.client.loop_stop() self.client.disconnect() print("[MQTT] 已断开连接") # 生产者线程:将消息放入队列 def producer_thread(): # message_queue.put(mess) for i in range(100): message = f"Message {i}" message_queue.put(message) print(f"生产者线程:已将消息放入队列: {message}") # time.sleep(1) # 模拟生产间隔 # 消费者线程:从队列中取出消息并发布 def consumer_thread(mqtt_client): print("consumer_thread") # while True: # try: # message = message_queue.get(timeout=1) # 设置超时以避免无限阻塞 # mqtt_client.publish_message(message) # message_queue.task_done() # 标记任务完成 # except queue.Empty: # print("消费者线程:队列为空,等待中...") # time.sleep(3) # 避免频繁检查队列 if __name__ == "__main__": # 初始化 MQTT 客户端 mqtt_client = MQTTClient(broker, port, topic) while True: try: raw_message = global_message_queue.get() # 阻塞等待消息 if raw_message is None: # 终止信号 break logger.debug(f"处理原始消息: {raw_message}") try: # 解析JSON消息 # task_data = json.loads(raw_message) logger.info(f"收到新任务: {raw_message}") print(f"收到新任务: {raw_message}") # # 处理任务 # result = process_uv_task(task_data) # # # 发布结果 # if result: # mqtt_manager.publish(MQTT_PUBLISH_TOPIC, result) except json.JSONDecodeError: logger.error("无效的JSON格式") except Exception as e: logger.error(f"消息处理过程中发生错误: {e}") except KeyboardInterrupt: logger.info("收到中断信号,停止消息处理...") break except Exception as e: logger.error(f"消息处理循环发生未预期错误: {e}") time.sleep(1) # 避免频繁错误导致CPU占用过高