Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT updates not working while changing Networks #448

Closed
nilsorathiya opened this issue Feb 24, 2023 · 9 comments
Closed

MQTT updates not working while changing Networks #448

nilsorathiya opened this issue Feb 24, 2023 · 9 comments

Comments

@nilsorathiya
Copy link

nilsorathiya commented Feb 24, 2023

I open the application with Wifi and Mobile both ON status and so MQTT connected successfully because it's initialized in the MAIN file, and I also got messages in MQTT.UPDATES.LISTEN callbacks.

My App is in foreground mode and now I am turning off the Wifi at that time, Auto Reconnected called and also resubscribed the topic but I am not getting any response in MQTT.UPDATES.LISTEN callbacks.

@shamblett
Copy link
Owner

OK I'll need a log from the autoreconnect point onwards.

When you say you resubscribed do you have an onSubscribe callback to check if the subscription worked?

@nilsorathiya
Copy link
Author

nilsorathiya commented Mar 4, 2023

Thanks, @shamblett for your quick response.
Before subscribing to a topic, I am checking existing subscriptions and if a new topic does not exist then only I am subscribing.

Subscriptions are happening correctly, but I am not sure what should I do when the network changes by User.
I am not receiving updates while user has only this case,

Let's say as an example, that User A has Mobile Data and Wifi both connected while using the app but when the user turns off the WIFI, I get a callback from the network listener about the network being disconnected and that same time, I am disconnecting the MQTT and when I am receiving callback of network about mobile data is connected, I am calling below connectMQTT function. This same function calls(main function) when a user opens an app from killed mode.

connectMQTT(){
try {
  debugPrint('NEW 🦟 MQTT2 🦟 CONNECT FROM $from');
  await newMQTTclient!.connect();

  if (newMQTTclient!.connectionStatus!.state ==
      MqttConnectionState.connected) {
    debugPrint('NEW 🦟 MQTT2 🦟 CONNECTED');
  } else {
    /// Use status here rather than state if you also want the broker return code.
    debugPrint(
        'NEW 🦟 MQTT2 🦟 DISCONNECTING ${newMQTTclient!.connectionStatus}');
    newMQTTclient!.disconnect();
    exit(-1);
  }

  debugPrint('NEW 🦟 MQTT2-CHECK:: ${newMQTTclient == null}');
  debugPrint(
      'NEW 🦟 MQTT2-UPDATE CHECK:: ${newMQTTclient!.updates == null}');

  newMQTTclient!.published!.listen((MqttPublishMessage message) {
    var payload =
        MqttPublishPayload.bytesToStringAsString(message.payload.message);
    debugPrint('NEW 🦟 MQTT2 PUBLISHED:: ${payload}');
  });

  newMQTTclient!.updates!.listen(
    (List<MqttReceivedMessage<MqttMessage?>>? c) {
      debugPrint('NEW 🦟 MQTT2 ON UPDATES - {$c}');
      for (int i = 0; i < c!.length; i++) {
        final MqttPublishMessage message =
            c[i].payload as MqttPublishMessage;
        var payload = MqttPublishPayload.bytesToStringAsString(
            message.payload.message);
        debugPrint(
            "NEW 🦟 MQTT2 🦟 RESPONSE NEW  ${DateTime.now()} $payload");
        DeviceResponseUtils()
            .handleResponse(str: payload, ipAddress: "", isMqtt: true);
      }
    },
    cancelOnError: true,
    onError: (Object error) {
      debugPrint('NEW 🦟 MQTT2 ON ERROR - UPDATES');
    },
    onDone: () {
      debugPrint('NEW 🦟 MQTT2 ON DONE - UPDATES');
    },
  );

} on NoConnectionException catch (e) {
  debugPrint('${DateTime.now()} NEW 🦟 MQTT2 🦟 :client exception - $e');
  newMQTTclient!.disconnect();
} on SocketException catch (e) {
  debugPrint('${DateTime.now()} NEW 🦟 MQTT2 🦟 :socket exception - $e');
  newMQTTclient!.disconnect();
}

subscribeDevices();
}
 void subscribeDevices({String? from}) {
    await Device().fetchAllNewDevices().then((listDevice) {
      for (var device in listDevice) {
        subscribeTopics(device, from: from);
      }
    });
  }
Future<void> subscribeTopics(DeviceResponse? deviceResponse,
    {String? from}) async {
  if (newMQTTclient != null &&
      newMQTTclient!.connectionStatus!.state ==
          MqttConnectionState.connected) {
    String topicToSubscribe =
        generateSlaveFromDeviceId(deviceId: deviceResponse!.deviceId!) +
            newMqttSubscribeTopic;
    debugPrint("NEW 🦟 MQTT2 🦟 TOPIC TO SUBSCRIBE --> $topicToSubscribe");

    debugPrint(
        "NEW 🦟 MQTT2 🦟 SUBSCRIPTIONS --> ${newMQTTclient!.subscriptionsManager!.subscriptions}");

    if (newMQTTclient!.subscriptionsManager != null &&
        newMQTTclient!.subscriptionsManager!.subscriptions
            .containsKey(topicToSubscribe)) {
      debugPrint(
          "NEW 🦟 MQTT2 🦟 SUBSCRIBE ALREADY ACTIVE--> $topicToSubscribe");
      sendDS(deviceResponse);
    } else {
      debugPrint(
          "NEW 🦟 MQTT2 🦟 CURRENT SUBSCRIPTIONS--> ${newMQTTclient!.subscriptionsManager!.subscriptions}}");

      newMQTTclient!.subscribe(topicToSubscribe, MqttQos.atMostOnce);
    }
  }
}

@shamblett
Copy link
Owner

OK but I still need a log as I said above, I need to see whats happening at run time.

@nilsorathiya
Copy link
Author

nilsorathiya commented Mar 4, 2023

Okay, I got an issue and this time you don't need logs.

.....
mqttClient!.autoReconnect = true;
mqttClient!.onAutoReconnected = onAutoReconnected;
await mqttClient!.connect();
.....

I am using an app with Mobile and Wifi both in ON status and when I switch off the Wifi, the Network listener callback with No Internet and at that time I am doing client. disconnect() and just after microseconds, I again got a callback from Network Listener is, Network is connected to Mobile and in that case, I am calling the function to connect to MQTT again.

I also got a connected event when I connect to MQTT again but I also got the event in the onAutoReconnected function which is of 1st MQTT connection and just after that updates stopped working.

And so for a final solution, I set autoReconnect as false and manually connect and disconnect when the network state changes.

ONE IMPORTANT THING IS,
WHY I AM GETTING EVENT IN onAutoReconnected if I already did client. disconnect()

@nilsorathiya
Copy link
Author

nilsorathiya commented Mar 5, 2023 via email

@shamblett
Copy link
Owner

I'm not unerstanding you, why can't you use the onConnected and onDisconnected callbacks? Note the API comment from onDisconnected -

 /// Client disconnect callback, called on unsolicited disconnect.
  /// This will not be called even if set if [autoReconnect} is set,instead
  /// [AutoReconnectCallback] will be called.

@nilsorathiya
Copy link
Author

nilsorathiya commented Mar 5, 2023 via email

@shamblett
Copy link
Owner

Please have a look at the API -

/// Client disconnect callback, called on unsolicited disconnect.
  /// This will not be called even if set if [autoReconnect} is set,instead
  /// [AutoReconnectCallback] will be called.
  DisconnectCallback? onDisconnected;

  /// Client connect callback, called on successful connect
  ConnectCallback? onConnected;

  /// Auto reconnect callback, if auto reconnect is selected this callback will
  /// be called before auto reconnect processing is invoked to allow the user to
  /// perform any pre auto reconnect actions.
  AutoReconnectCallback? onAutoReconnect;

  /// Auto reconnected callback, if auto reconnect is selected this callback will
  /// be called after auto reconnect processing is completed to allow the user to
  /// perform any post auto reconnect actions.
  AutoReconnectCompleteCallback? onAutoReconnected;

If you hook these up(assuming you are using autoreconnect) then when onAutoReconnect is called then you can tell your user that they are disconnected until onAutoReconnected is called, similarly if you are not using autoreconnect for onDisconnected/onConnected.

@nilsorathiya
Copy link
Author

nilsorathiya commented Mar 5, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants