Handle broker-initiated MQTT disconnects in the Flutter client
I maintainer di solito rispondono entro 5 giorni
@bracyw ci sta già lavorando.
Dal 6/9/2026.
Valutazione
Questa issue non è ancora stata valutata.
Descrizione
Problem
A DISCONNECT packet sent by the broker permanently kills telemetry in the Flutter client, with no error and no recovery.
The client is wired up once and never touched again: base_data.dart:167-170 connects, subscribes, and attaches exactly one listener to the updates stream. There is no onDisconnected callback, no onAutoReconnected, and nothing ever re-listens.
In mqtt5_client 5.0.0 that is not enough:
- MqttClient.connect registers a handler for broker DISCONNECT packets (mqtt_client.dart:300-303). When one arrives, _processReceivedDisconnectMessage (mqtt_client.dart:647-657) calls _disconnect with fromBroker true.
- _disconnect (mqtt_client.dart:575-606) nulls subscriptionsManager, publishingManager, keepAlive and connectionHandler, and destroys the event bus. It never consults autoReconnect. Since the updates getter is just subscriptionsManager?.subscriptionNotifier (mqtt_client.dart:274-275), client.updates becomes null.
- The broadcast controller behind the old stream is never closed, so the listener from base_data.dart:170 gets no onDone and no onError. It simply stops receiving.
- Auto-reconnect is bypassed entirely. The reconnect machinery lives in internalDisconnect (mqtt_client.dart:550-572), which is only reached from the connection-level onDisconnected callback — and by then connectionHandler is null, so it returns immediately.
The provider keeps its last AsyncData and the stream at base_data.dart:195 stays open and goes quiet. Nothing errors, so the Retry button in data_page.dart:36-41, which is only rendered for AsyncError, never appears. The UI shows frozen telemetry that is indistinguishable from a stationary car.
Reproduction
Verified against mosquitto 2.1.2 and mqtt5_client 5.0.0, using a harness that mirrors base_data.dart:151-193 exactly (same client construction, keepAlivePeriod 5, autoReconnect true, resubscribeOnAutoReconnect true, startClean, subscribe to the wildcard, one listener).
Trigger: session takeover — connect a second client using the same client identifier, which makes the broker send DISCONNECT with reason 0x8E to the first.
Observed — messages arriving steadily for 10s, then at the takeover:
+10.0s msgs=3 state=connected updatesNull=false subMgrNull=false connHandlerNull=false
+11.0s msgs=0 state=disconnected updatesNull=true subMgrNull=true connHandlerNull=true
...
+25.0s msgs=0 state=disconnected updatesNull=true subMgrNull=true connHandlerNull=true
with disconnectionOrigin brokerSolicited. Zero further messages, no exception, no stream completion.
Control: killing the broker outright, so the socket just drops with no DISCONNECT packet, recovers correctly — auto-reconnect fires, the single listener survives, and telemetry resumes after about 5s. An ordinary network blip is genuinely fine. It is specifically the DISCONNECT packet that is fatal.
How reachable is this today
Narrow, but the blast radius is total and silent, and this is a car telemetry client.
- Keep-alive timeout, the obvious trigger, is currently closed off by the related defect below.
- A mosquitto restart does not trigger it. mosquitto 2.1.2 terminates without sending DISCONNECT, and the client auto-reconnects.
- Session takeover needs a client identifier collision, and base_data.dart:153 builds the identifier from milliseconds since epoch, so two clients would have to connect within the same millisecond.
- Any broker-side administrative disconnect, quota or rate-limit kick, or protocol-error DISCONNECT does trigger it. These are standard MQTT 5 broker behaviours and the client should tolerate them regardless of what the current mosquitto config happens to emit.
Related defect found while verifying
The keepAlivePeriod of 5 set at base_data.dart:161 never reaches the broker. mqtt5_client uses that value only to drive its own local ping timer (mqtt_client.dart:319-327); the keep-alive field in the CONNECT packet is set exclusively via keepAliveFor on the connect message, and base_data.dart:164 supplies a connect message without it. The broker logs the client as k0, meaning keep-alive disabled. So mosquitto will never reap a half-open Argos connection, and the client's 5-second pings buy nothing broker-side.
What to do
- Set the keep-alive on the connect message so the broker actually enforces it.
- Set onDisconnected, and on a broker-solicited disconnect either rebuild the client fully (reconnect, resubscribe, re-listen) or surface an error on the provider so the existing Retry path becomes reachable.
- Do not assume the listener attached at connect time survives a teardown; after one, client.updates is a different stream.
- Lingua principale
- TypeScript
- Stelle
- 5
- Fork
- 1
- Merge medio
- 5g 13h
- PR unite (30g)
- 24
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Northeastern-Electric-Racing/Argos
-
Deliver telemetry selectively per screen over the existing Socket.IO transportForse già presa @bracyw l’ha presa 17 giorni fa. Apertaangular-client difficult new feature scylla-server
Northeastern-Electric-Racing/Argos#777 · 1 assegnatario ·
I maintainer di solito rispondono entro 5 giorni
-
Prune CONTEXT.md glossary to genuinely ambiguous termsForse di nuovo libera @bracyw l’ha presa 76 giorni fa e non c’è nessuna pull request aperta. Apertaai-workflow needs-triage
Northeastern-Electric-Racing/Argos#716 · 1 assegnatario ·
I maintainer di solito rispondono entro 5 giorni
-
Fix clipped content on BMS segment-detail cards at ~1028px widthForse di nuovo libera @bracyw l’ha presa 76 giorni fa e non c’è nessuna pull request aperta. Apertaangular-client bug needs-triage straightforward
Northeastern-Electric-Racing/Argos#715 · 1 assegnatario ·
I maintainer di solito rispondono entro 5 giorni
-
Fix BMS At A Glance stat overlap and clipping at narrow widthsForse di nuovo libera @bracyw l’ha presa 76 giorni fa e non c’è nessuna pull request aperta. Apertaangular-client bug medium needs-triage
Northeastern-Electric-Racing/Argos#714 · 1 assegnatario ·
I maintainer di solito rispondono entro 5 giorni
-
Fix blank BMS page below 768px (isMobile placeholder renders nothing)Forse di nuovo libera @bracyw l’ha presa 76 giorni fa e non c’è nessuna pull request aperta. Apertaangular-client bug needs-triage straightforward
Northeastern-Electric-Racing/Argos#713 · 1 assegnatario ·
I maintainer di solito rispondono entro 5 giorni
Tutte le issue di Northeastern-Electric-Racing/Argos
Issue simili
-
needs:triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno
-
ai-discovered
Difficoltà 2/5 1-3 ore Idoneità per principianti 83/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
jessepollak/home#1627 ·
I maintainer di solito rispondono entro 1 giorno
-
agent-canvas bug llm priority:low ready-for-dev
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
OpenHands/OpenHands#17806 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
radius-project/ai-extensions#923 ·
I maintainer di solito rispondono entro 1 giorno