fix: 首次握手失败停止重连并修正 Java 限速在途计数

This commit is contained in:
Nixevol
2026-09-30 19:18:47 +08:00
parent 08c08de5e8
commit 9c6de00ea0
6 changed files with 210 additions and 12 deletions
+22 -7
View File
@@ -8,16 +8,23 @@ from dataclasses import dataclass, field
from typing import Any, Callable, Optional, Protocol
from urllib.parse import urlparse
from paho.mqtt.client import CallbackAPIVersion, Client as PahoClient, MQTT_ERR_SUCCESS, MQTTv5
from paho.mqtt.enums import MQTTErrorCode
from paho.mqtt.reasoncodes import ReasonCode
DownHandler = Callable[[bytes], None]
ConnHandler = Callable[[], None]
DiscHandler = Callable[[Optional[str], bool], None]
# reason_code_str, stop_reconnect
def _require_paho():
"""真实 MQTT 路径才加载 paho;假传输单测不依赖。"""
try:
from paho.mqtt.client import CallbackAPIVersion, Client as PahoClient, MQTT_ERR_SUCCESS, MQTTv5
from paho.mqtt.enums import MQTTErrorCode
from paho.mqtt.reasoncodes import ReasonCode
except ImportError as e:
raise ImportError("需要 paho-mqtt>=2.0(真实 MQTT 连接)") from e
return CallbackAPIVersion, PahoClient, MQTT_ERR_SUCCESS, MQTTv5, MQTTErrorCode, ReasonCode
@dataclass
class ConnectParams:
url: str
@@ -180,7 +187,7 @@ class PahoTransport:
"""paho-mqtt 2.x CallbackAPIVersion.VERSION2。"""
def __init__(self) -> None:
self._client: Optional[PahoClient] = None
self._client: Any = None
self._on_connected: Optional[ConnHandler] = None
self._on_disconnected: Optional[DiscHandler] = None
self._on_down: Optional[DownHandler] = None
@@ -200,6 +207,7 @@ class PahoTransport:
self._on_down = on_down
def connect(self, params: ConnectParams) -> None:
CallbackAPIVersion, PahoClient, _, MQTTv5, _, _ = _require_paho()
self.disconnect()
url = params.url
u = urlparse(url if "://" in url else "ws://" + url)
@@ -261,6 +269,7 @@ class PahoTransport:
# 等待连接结果由回调驱动;超时由 Client 层处理
def subscribe(self, topic: str) -> None:
_, _, MQTT_ERR_SUCCESS, _, _, _ = _require_paho()
self._down_topic = topic
if not self._client:
return
@@ -273,6 +282,7 @@ class PahoTransport:
raise RuntimeError("subscribe timeout")
def publish(self, topic: str, payload: bytes) -> None:
_, _, MQTT_ERR_SUCCESS, _, _, _ = _require_paho()
if not self._client:
raise RuntimeError("not connected")
info = self._client.publish(topic, payload, qos=1)
@@ -338,9 +348,14 @@ def _reason_to_int(reason_code) -> Optional[int]:
return None
if isinstance(reason_code, int):
return reason_code
if isinstance(reason_code, ReasonCode):
try:
_, _, _, _, MQTTErrorCode, ReasonCode = _require_paho()
except ImportError:
MQTTErrorCode = () # type: ignore[assignment,misc]
ReasonCode = () # type: ignore[assignment,misc]
if ReasonCode and isinstance(reason_code, ReasonCode):
return int(reason_code.value)
if isinstance(reason_code, MQTTErrorCode):
if MQTTErrorCode and isinstance(reason_code, MQTTErrorCode):
return int(reason_code)
# paho 偶发其它包装
val = getattr(reason_code, "value", None)