shamblett / mqtt_client

A server and browser based MQTT client for dart
Other
548 stars 176 forks source link

When is release the version 8.0.0? #219

Closed xhidnoda closed 4 years ago

xhidnoda commented 4 years ago

I looking forward to use and test the the new resubscribeOnAutoReconnect on Flutter.

This is a big problem for Flutter developers...The problem is exactly when te APP goes to background apparently the mqtt_client lost the subscribe list.

Any help?

shamblett commented 4 years ago

The code updates have been tested against the hive broker and work OK, there is a slight problem however when I use mosquito but I still envisage re publishing this week.

Just a note here auto reconnect was designed to reconnect on loss of the network/broker, while the process stayed alive, not if the process is somehow suspended thus disconnecting itself. I'm not saying these updates won't work or help but other things may be happening when you come out of background that have not been anticipated yet.

xhidnoda commented 4 years ago

@shamblett Thanks!

I know you not are Flutter developer but, can you suggest me how keep the connection and the subscription list after come back from background?

By now for detecting when the app come back from background i use this code:

handleAppLifecycleState() {
  AppLifecycleState _lastLifecyleState;
  SystemChannels.lifecycle.setMessageHandler((msg) {

    print('SystemChannels> $msg');

    switch (msg) {
      case "AppLifecycleState.paused":
        _lastLifecyleState = AppLifecycleState.paused;
        print('Estado: '+ _lastLifecyleState.toString());
        break;
      case "AppLifecycleState.inactive":
        _lastLifecyleState = AppLifecycleState.inactive;
        print('Estado: '+ _lastLifecyleState.toString());
        break;
      case "AppLifecycleState.resumed":
        _lastLifecyleState = AppLifecycleState.resumed;
        print('Estado: '+ _lastLifecyleState.toString());

        Get.to(SplashScreen());

        //ignore: missing_return, missing_return
        break;
      default:
    }

  });
}

In my SplashScreen() call the connect and subscription list, but don't work :(

shamblett commented 4 years ago

If you want to do this without using auto reconnect then at the moment when you initially subscribe to a topic you get the subscription back, keep these, on entry to background disconnect, you could at this point before you disconnect call unsubscribe for your subscriptions, go into background, when you come out connect again, then if you have not already unsubscribed unsubscribe, then re subscribe your topics.

In 8.0.0 there is a new API call named resubscribe, this will do a local unsubscribe of all your subscriptions allowing you to re subscribe by topic, so in 8.0.0 you could on entry into background call unsubscribe then disconnect, then when you come out you will just need to re subscribe by topic again after connecting.

Note that resubscribe is local only, it does NOT send an unsubscribe to the broker, most brokers are OK with this when you re subscribe the same subscription.

If you use auto reconnect and leave resubscribeOnAutoReconnect defaulted this will be done for you when you emerge from background, well that's the plan anyway.

This is getting quite complex, we seem to need an auto reconnect mechanism for when we just lose connection to the broker but do not go into background and a separate one for going into background and out again.

Any thoughts welcome.

xhidnoda commented 4 years ago

Ok i solve this (but a have a new problem: the result of response is duplicating, this is just my problem for sure)

Here my steps:

For detecting when the APP goes paused - inactive and resume i use this code: (Use this in whatever your like, in my case i call in the MqttConnection.dart)

handleAppLifecycleState() {
  String deviceID;
  AppLifecycleState _lastLifecyleState;

  void setupAppPreferences() async {
    deviceID = await SharedPreferencesHelper.getDeviceID();
  }

  SystemChannels.lifecycle.setMessageHandler((msg) {

    print('SystemChannels> $msg');

    switch (msg) {
      case "AppLifecycleState.paused":
        _lastLifecyleState = AppLifecycleState.paused;
        print('Estado: '+ _lastLifecyleState.toString());

        MqttConnection.mClient.disconnect();

        break;
      case "AppLifecycleState.inactive":
        _lastLifecyleState = AppLifecycleState.inactive;
        print('Estado: '+ _lastLifecyleState.toString());
        break;
      case "AppLifecycleState.resumed":
        _lastLifecyleState = AppLifecycleState.resumed;
        print('Estado: '+ _lastLifecyleState.toString());

        setupAppPreferences();

        new Future.delayed(new Duration(seconds: 2), () {
          GlobalFunction().checkNetworkAvailable().then((onValue) {
            if (onValue) {

              print('LOG: TRATANDO DE CONECTAR AL BROKER MQTT...');

              if (!MqttConnection().connectionStatus()) {
                MqttConnection(
                    mUsername: ApiConnect.username,
                    mPassword: ApiConnect.password,
                    mBrokerUrl: ApiConnect.serverIp,
                    mClientId: deviceID.substring(0, 20))
                    .connectToMqtt();
              } else {
                print("LOG: error al tratar de conseguir connectionStatus");
              }
            } else {
              print('LOG: ERROR AL CONECTAR A INTERNET...');
            }
          });

        });

        //ignore: missing_return, missing_return
        break;
      default:
    }

  });
}

So, when the APP go pause or inactive, call the MqttConnection.mClient.disconnect(); and then when the APP comeback again i call the connection. Where the connection have a subscription list.

BUT, anyway i waiting the 8.0.0 version to this scenario.

Thanks @shamblett