mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-03-28 17:42:45 +01:00
fix: disable buggy library auto-reconnect, handle reconnection ourselves
meshcore 2.3.0's ConnectionManager has a bug: when auto-reconnect creates a new TCP connection, the old connection's connection_lost callback fires, triggering another reconnect cycle. Since each success resets the attempt counter, this loops forever (~1 TCP connection/second). Disabled library auto_reconnect and added reconnection logic to _on_disconnected() with 3 attempts and increasing backoff (5/10/15s). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -149,14 +149,19 @@ class DeviceManager:
|
||||
self.mc = await MeshCore.create_tcp(
|
||||
host=self.config.MC_TCP_HOST,
|
||||
port=self.config.MC_TCP_PORT,
|
||||
auto_reconnect=self.config.MC_AUTO_RECONNECT,
|
||||
# Disable library auto-reconnect — it has a bug where old
|
||||
# connection's close callback triggers infinite reconnect loop.
|
||||
# We handle reconnection ourselves in _on_disconnected().
|
||||
auto_reconnect=False,
|
||||
)
|
||||
else:
|
||||
port = self._detect_serial_port()
|
||||
logger.info(f"Connecting via serial: {port}")
|
||||
self.mc = await MeshCore.create_serial(
|
||||
port=port,
|
||||
auto_reconnect=self.config.MC_AUTO_RECONNECT,
|
||||
# Disable library auto-reconnect — same bug as TCP.
|
||||
# We handle reconnection ourselves in _on_disconnected().
|
||||
auto_reconnect=False,
|
||||
)
|
||||
|
||||
# Read device info
|
||||
@@ -953,7 +958,7 @@ class DeviceManager:
|
||||
logger.error(f"Error handling new contact: {e}")
|
||||
|
||||
async def _on_disconnected(self, event):
|
||||
"""Handle device disconnection."""
|
||||
"""Handle device disconnection with auto-reconnect."""
|
||||
logger.warning("Device disconnected")
|
||||
self._connected = False
|
||||
|
||||
@@ -962,6 +967,25 @@ class DeviceManager:
|
||||
'connected': False,
|
||||
}, namespace='/chat')
|
||||
|
||||
# Auto-reconnect with backoff
|
||||
for attempt in range(1, 4):
|
||||
delay = 5 * attempt
|
||||
logger.info(f"Reconnecting in {delay}s (attempt {attempt}/3)...")
|
||||
await asyncio.sleep(delay)
|
||||
try:
|
||||
await self._connect()
|
||||
if self._connected:
|
||||
logger.info("Reconnected successfully")
|
||||
if self.socketio:
|
||||
self.socketio.emit('device_status', {
|
||||
'connected': True,
|
||||
}, namespace='/chat')
|
||||
return
|
||||
except Exception as e:
|
||||
logger.error(f"Reconnect attempt {attempt} failed: {e}")
|
||||
|
||||
logger.error("Failed to reconnect after 3 attempts")
|
||||
|
||||
# ================================================================
|
||||
# Command Methods (sync — called from Flask routes)
|
||||
# ================================================================
|
||||
|
||||
Reference in New Issue
Block a user