From 547ee7cd0045d5604d143733d37a3d02f52ad1b8 Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Tue, 24 Mar 2026 02:11:51 +0100
Subject: [PATCH] fix: force MQTT reconnect on app resume to avoid stale connections
---
lib/services/mqtt_service.dart | 18 ++++++++++++++++--
1 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/lib/services/mqtt_service.dart b/lib/services/mqtt_service.dart
index f7a51be..35464de 100644
--- a/lib/services/mqtt_service.dart
+++ b/lib/services/mqtt_service.dart
@@ -514,11 +514,25 @@
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.resumed:
- if (_status != ConnectionStatus.connected && !_intentionalClose) {
+ if (_intentionalClose) break;
+ // iOS kills the TCP socket during suspend. The MQTT client may still
+ // think it's connected until the next ping timeout (30s+). Force a
+ // fresh connection to avoid the "dead but looks alive" state.
+ final client = _client;
+ if (client != null && client.connectionStatus?.state == MqttConnectionState.connected) {
+ // Verify the connection is actually alive by checking disconnect state
+ // If auto-reconnect already fired, this is a no-op
+ _mqttLog('MQTT: app resumed, verifying connection...');
+ // Force disconnect + reconnect to get a clean state
+ client.autoReconnect = false;
+ client.disconnect();
+ _client = null;
+ _setStatus(ConnectionStatus.reconnecting);
+ Future.delayed(const Duration(milliseconds: 500), () => connect());
+ } else if (_status != ConnectionStatus.connected) {
connect();
}
case AppLifecycleState.paused:
- // Keep connection alive — MQTT handles keepalive natively
break;
default:
break;
--
Gitblit v1.3.1