| .. | .. |
|---|
| 107 | 107 | _intentionalClose = false; |
|---|
| 108 | 108 | _setStatus(ConnectionStatus.connecting); |
|---|
| 109 | 109 | |
|---|
| 110 | | - // Start listening for network changes (WiFi↔cellular, VPN connect/disconnect) |
|---|
| 111 | | - _connectivitySub ??= Connectivity().onConnectivityChanged.listen((results) { |
|---|
| 112 | | - if (_lastConnectivity != null && !_intentionalClose) { |
|---|
| 113 | | - final changed = results.length != _lastConnectivity!.length || |
|---|
| 114 | | - !results.every((r) => _lastConnectivity!.contains(r)); |
|---|
| 115 | | - if (changed) { |
|---|
| 116 | | - _mqttLog('MQTT: network changed: ${results.map((r) => r.name).join(",")} — forcing reconnect'); |
|---|
| 117 | | - // Force disconnect and reconnect on new network |
|---|
| 118 | | - final client = _client; |
|---|
| 119 | | - if (client != null) { |
|---|
| 120 | | - _intentionalClose = true; |
|---|
| 121 | | - client.autoReconnect = false; |
|---|
| 122 | | - try { client.disconnect(); } catch (_) {} |
|---|
| 123 | | - _client = null; |
|---|
| 124 | | - _updatesSub?.cancel(); |
|---|
| 125 | | - _updatesSub = null; |
|---|
| 126 | | - _intentionalClose = false; |
|---|
| 127 | | - } |
|---|
| 128 | | - _lastDiscoveredHost = null; // Clear cached discovery — subnet may have changed |
|---|
| 129 | | - connectedHost = null; |
|---|
| 130 | | - connectedVia = null; |
|---|
| 131 | | - _setStatus(ConnectionStatus.reconnecting); |
|---|
| 132 | | - Future.delayed(const Duration(milliseconds: 500), () { |
|---|
| 133 | | - if (!_intentionalClose) connect(); |
|---|
| 134 | | - }); |
|---|
| 135 | | - } |
|---|
| 136 | | - } |
|---|
| 137 | | - _lastConnectivity = results; |
|---|
| 138 | | - }); |
|---|
| 110 | + // Network change detection disabled — was causing spurious reconnects. |
|---|
| 111 | + // MQTT keepalive + auto-reconnect handles dead connections reliably. |
|---|
| 139 | 112 | |
|---|
| 140 | 113 | // Load trusted cert fingerprint for TOFU verification |
|---|
| 141 | 114 | if (_trustedFingerprint == null) await _loadTrustedFingerprint(); |
|---|