fix(mqtt): 修复 MQTT 连接反复断开重连的问题
- 协议从 MQTTv5 降级为 MQTTv311,提高兼容性 - client_id 添加随机后缀,防止多实例冲突导致互相踢连接 - 修复 on_connect/on_disconnect 回调的参数解析逻辑 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ MQTT 订阅服务
|
|||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
import threading
|
import threading
|
||||||
|
import uuid
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import Callable, Dict, Any, Optional, List
|
from typing import Callable, Dict, Any, Optional, List
|
||||||
|
|
||||||
@@ -59,20 +60,23 @@ class MQTTService:
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# 给 client_id 添加随机后缀,防止多实例 client_id 冲突导致反复踢连接
|
||||||
|
unique_client_id = f"{settings.mqtt.client_id}_{uuid.uuid4().hex[:8]}"
|
||||||
|
|
||||||
# 兼容 paho-mqtt 1.x 和 2.x 版本
|
# 兼容 paho-mqtt 1.x 和 2.x 版本
|
||||||
try:
|
try:
|
||||||
# paho-mqtt 2.0+ 新 API
|
# paho-mqtt 2.0+ 新 API
|
||||||
self._client = mqtt.Client(
|
self._client = mqtt.Client(
|
||||||
client_id=settings.mqtt.client_id,
|
client_id=unique_client_id,
|
||||||
protocol=mqtt.MQTTv5,
|
protocol=mqtt.MQTTv311,
|
||||||
callback_api_version=mqtt.CallbackAPIVersion.VERSION2
|
callback_api_version=mqtt.CallbackAPIVersion.VERSION2
|
||||||
)
|
)
|
||||||
self._use_v2_callback = True
|
self._use_v2_callback = True
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# paho-mqtt 1.x 旧 API
|
# paho-mqtt 1.x 旧 API
|
||||||
self._client = mqtt.Client(
|
self._client = mqtt.Client(
|
||||||
client_id=settings.mqtt.client_id,
|
client_id=unique_client_id,
|
||||||
protocol=mqtt.MQTTv5
|
protocol=mqtt.MQTTv311
|
||||||
)
|
)
|
||||||
self._use_v2_callback = False
|
self._use_v2_callback = False
|
||||||
logger.info("使用 paho-mqtt 1.x 兼容模式")
|
logger.info("使用 paho-mqtt 1.x 兼容模式")
|
||||||
@@ -124,11 +128,14 @@ class MQTTService:
|
|||||||
"""连接回调 (兼容 1.x 和 2.x)"""
|
"""连接回调 (兼容 1.x 和 2.x)"""
|
||||||
# 1.x: (client, userdata, flags, rc)
|
# 1.x: (client, userdata, flags, rc)
|
||||||
# 2.x: (client, userdata, connect_flags, reason_code, properties)
|
# 2.x: (client, userdata, connect_flags, reason_code, properties)
|
||||||
|
rc = 0
|
||||||
if args:
|
if args:
|
||||||
reason_code = args[-2] if len(args) >= 2 else args[-1]
|
# 取倒数第二个参数(1.x 的 rc 或 2.x 的 reason_code)
|
||||||
rc = reason_code if isinstance(reason_code, int) else getattr(reason_code, 'value', reason_code)
|
if len(args) >= 2:
|
||||||
else:
|
reason_code = args[-2]
|
||||||
rc = -1
|
else:
|
||||||
|
reason_code = args[0]
|
||||||
|
rc = reason_code if isinstance(reason_code, int) else getattr(reason_code, 'value', 0)
|
||||||
|
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
self._connected = True
|
self._connected = True
|
||||||
@@ -149,12 +156,17 @@ class MQTTService:
|
|||||||
# 1.x: (client, userdata, rc)
|
# 1.x: (client, userdata, rc)
|
||||||
# 2.x: (client, userdata, disconnect_flags, reason_code, properties)
|
# 2.x: (client, userdata, disconnect_flags, reason_code, properties)
|
||||||
self._connected = False
|
self._connected = False
|
||||||
|
rc = 0
|
||||||
if args:
|
if args:
|
||||||
reason_code = args[-2] if len(args) >= 2 else args[0]
|
if len(args) >= 2:
|
||||||
rc = reason_code if isinstance(reason_code, int) else getattr(reason_code, 'value', reason_code)
|
reason_code = args[-2]
|
||||||
logger.warning(f"MQTT 连接断开: {rc}")
|
else:
|
||||||
|
reason_code = args[0]
|
||||||
|
rc = reason_code if isinstance(reason_code, int) else getattr(reason_code, 'value', 0)
|
||||||
|
if rc != 0:
|
||||||
|
logger.warning(f"MQTT 连接异常断开: rc={rc}")
|
||||||
else:
|
else:
|
||||||
logger.warning("MQTT 连接断开")
|
logger.info("MQTT 连接断开")
|
||||||
|
|
||||||
def _on_message(self, client, userdata, msg: mqtt.MQTTMessage):
|
def _on_message(self, client, userdata, msg: mqtt.MQTTMessage):
|
||||||
"""消息回调"""
|
"""消息回调"""
|
||||||
|
|||||||
Reference in New Issue
Block a user