Closed iosephmagno closed 1 year ago
OK, when you execute step 2 do you get an onDisconnected callback? If you haven't hooked this up in your code please do so.
If you are calling this callback please supply a log of what happens when its called.
If its not called then the runtime is not signalling to the client that a disconnect to the broker has occurred, the client can't do much about this.
Thx! Yes, we call the callback.
Future<void> connect({
required String clientId,
required String userid,
}) async {
client.port = AppConfig.mqttport;
client.logging(on: loggerOn);
client.keepAlivePeriod = 1200;
client.onConnected = onConnected;
client.onDisconnected = onDisconnected;
client.secure = false; //true for secure connection
client.autoReconnect = true; //true to automatically reconnect
client.onSubscribed = onSubscribed;
client.onAutoReconnect = onAutoReconnect;
client.onUnsubscribed = onUnSubscribed;
client.resubscribeOnAutoReconnect = true;
client.disconnectOnNoResponsePeriod = 1; //1 second
client.manuallyAcknowledgeQos1 = false;
....
void onDisconnected() {
debugPrint('Disconnected from MQTT Server server');
}
It looks like onDisconnected
is not invoked.
flutter: MQTT isConnected: true
flutter: MQTT client.connectionStatus!.state: MqttConnectionState.connected
Question: even if flutter doesnt signal the disconnection, can't we just grab the event of client not receiving messages from server and therefore set state to MqttConnectionState.disconnected
?
Just noticed we can workaround the issue with this package coz it gives a precise status about internet connection. https://pub.dev/packages/observe_internet_connectivity
InternetConnectivity()
.observeInternetConnection
.listen((bool hasInternetAccess) async {
...
But it seems a waste of resources to have a separate socket doing this job while we already have the mqtt connection. I would prefer getting mqtt connection status. If it is connected
then internet connection is ON, else we lookupWebsite() to rule out a false positive (mqtt client might be disconnected
but internet might be ON). This way we would use only mqtt.
I see from your code above you have keep alive enabled but you are not setting a disconnect period so the client will not disconnect you. Have a look at this parameter disconnectOnNoResponsePeriod in the client API, set this to say 5 for 5 seconds or whatever you prefer, when the client sees that no ping responses have been received from the broker for this period it will disconnect you.
Thx Steve, we will add it and revert CC: @josh4500
Just noticed you also have autoReconnect set, so you won't get onDisconnected, you'll get onAutoReconnect instead. You should then stay in autoreconnect until re connection is achieved, if you want to control this manually through onDisconnect then turn off autoreconnect.
Either way your connected status should now be correct.
@shamblett Connection status doesn't change if client is disconnected (after a connection was previously made). For now we do not rely on MQTT connection status.
If this is the case it sounds wrong, I'll need a log showing whats happening when disconnect occurs.
Seems to work here on isolation You can check here https://github.com/josh4500/mqtt_connection_test
I am very new to flutter / dart and this package, but I am experiencing a similar issue. I am using autoReconnect, and that functionality works. I am building a flutter windows desktop app. I launch my broker (shiftr.io desktop), then launch my app, it connects. I shut down broker, client disconnects, restart broker, and client reconnects, no problem. I am using a FutureBuilder like so:
FutureBuilder<MqttServerClient>(
future: connect(),
builder: (BuildContext context,
AsyncSnapshot<MqttServerClient> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
// If the Future is still running, return a loading indicator
return CircularProgressIndicator();
} else if (snapshot.hasError) {
// If we run into an error, display it to the user
return Text('Error: ${snapshot.error}');
} else if (snapshot.data == null) {
// Guard against null data
return Text('No Data');
} else {
// If the Future is complete and no errors occurred,
// check the connection status of the MQTT client
MqttConnectionState? state =
snapshot.data!.connectionStatus?.state;
if (state == MqttConnectionState.connected) {
return Text('Connected to MQTT Server');
} else if (state == MqttConnectionState.disconnected) {
return Text('Disconnected from MQTT Server');
} else {
// Handle other states or scenarios as required
return Text('Unknown State: $state');
}
}
},
),
I would expect the state == MqttConnectionState.disconnected
to update... debug console looks like this:
flutter: 1-2023-08-16 10:45:41.048090 -- MqttConnectionBase::_onDone - calling disconnected callback
flutter: 1-2023-08-16 10:45:41.049090 -- MqttConnectionHandlerBase::autoReconnect entered
flutter: EXAMPLE::onAutoReconnect client callback - Client auto reconnection sequence will start
flutter: 1-2023-08-16 10:45:41.050089 -- MqttConnectionHandlerBase::autoReconnect - attempting reconnection
Like I said I'm very new, hopefully this either helps or someone can point out my error... thanks!
taking a look at @josh4500 code above, trying locally...
okay @josh4500 thank you- I just learned about ValueNotifiers in Flutter and my code now works. Thanks very much for your example!
CC: @shamblett hope you don't mind me mentioning, but I'd really appreciate if you could help with this.
client.connectionStatus!.state
returns wrong value when user turns off Internet connection.To reproduce issue:
1) Connect to broker over cellular data (wifi should be off) 2) Turn off cellular data from device Internet setting
Result:
client.connectionStatus!.state
keeps returningMqttConnectionState.connected
Expected Result:
Client shouldn't be able to reach the broker and connectionStatus should be set to
MqttConnectionState.disconnected
or maybeMqttConnectReturnCode.noneSpecified
.Tested with v. 10.0.0 and 9.8.1 on ios 16.1, android 12 and android 13.