aws-amplify / aws-sdk-android

AWS SDK for Android. For more information, see our web site:
https://docs.amplify.aws
Other
1.03k stars 549 forks source link

Continous Mqtt Connection Successful -> Connection Lost -> Reconnect #2287

Closed armandr closed 2 years ago

armandr commented 3 years ago

Describe the bug Connecting to a pre-configured mqtt endpoint and policy that currently works fine with aws-ios-sdk.

Upon connection, the connection is then dropped without a reason provided. It is similar to https://github.com/aws-amplify/aws-sdk-android/issues/394 (the device does have the time/date set to automatic)

The set up is similar to the example provided in PubSub example here: https://github.com/awslabs/aws-sdk-android-samples/tree/9c81a6bb6aa3e74a4bba9a02b26681f355260e63/AndroidPubSub

2020-12-14 13:45:18.514 23999-24319/com.myorg.myapp I/AWSIotMqttManager: onSuccess: mqtt connection is successful. 2020-12-14 13:45:18.514 23999-24319/com.myorg.myapp I/iot: mqtt connect: Connected 2020-12-14 13:45:18.514 23999-24319/com.myorg.myapp D/iot: iot connected 2020-12-14 13:45:18.525 23999-24319/com.myorg.myapp W/AWSIotMqttManager: connection is Lost 2020-12-14 13:45:18.526 23999-24319/com.myorg.myapp I/AWSIotMqttManager: schedule Reconnect attempt 0 of 10 in 4 seconds. 2020-12-14 13:45:18.527 23999-24319/com.myorg.myapp I/iot: mqtt connect: Reconnecting 2020-12-14 13:45:22.533 23999-24322/com.myorg.myapp I/AWSIotMqttManager: attempting to reconnect to mqtt broker 2020-12-14 13:45:23.206 23999-24339/com.myorg.myapp I/AWSIotMqttManager: Reconnect successful 2020-12-14 13:45:23.207 23999-24339/com.myorg.myapp I/AWSIotMqttManager: Auto-resubscribe is enabled. Resubscribing to previous topics. 2020-12-14 13:45:23.208 23999-24339/com.myorg.myapp I/iot: mqtt connect: Connected 2020-12-14 13:45:23.208 23999-24339/com.myorg.myapp D/iot: iot connected 2020-12-14 13:45:23.218 23999-24339/com.myorg.myapp W/AWSIotMqttManager: connection is Lost 2020-12-14 13:45:23.220 23999-24339/com.myorg.myapp I/AWSIotMqttManager: schedule Reconnect attempt 1 of 10 in 8 seconds. 2020-12-14 13:45:23.223 23999-24339/com.myorg.myapp I/iot: mqtt connect: Reconnecting 2020-12-14 13:45:31.231 23999-24341/com.myorg.myapp I/AWSIotMqttManager: attempting to reconnect to mqtt broker 2020-12-14 13:45:31.914 23999-24349/com.myorg.myapp I/AWSIotMqttManager: Reconnect successful 2020-12-14 13:45:31.914 23999-24349/com.myorg.myapp I/AWSIotMqttManager: Auto-resubscribe is enabled. Resubscribing to previous topics. 2020-12-14 13:45:31.915 23999-24349/com.myorg.myapp I/iot: mqtt connect: Connected 2020-12-14 13:45:31.915 23999-24349/com.myorg.myapp D/iot: iot connected 2020-12-14 13:45:31.922 23999-24349/com.myorg.myapp W/AWSIotMqttManager: connection is Lost 2020-12-14 13:45:31.923 23999-24349/com.myorg.myapp I/AWSIotMqttManager: schedule Reconnect attempt 2 of 10 in 16 seconds. 2020-12-14 13:45:31.927 23999-24349/com.myorg.myapp I/iot: mqtt connect: Reconnecting 2020-12-14 13:45:47.936 23999-24351/com.myorg.myapp I/AWSIotMqttManager: attempting to reconnect to mqtt broker 2020-12-14 13:45:48.584 23999-24408/com.myorg.myapp I/AWSIotMqttManager: Reconnect successful 2020-12-14 13:45:48.584 23999-24408/com.myorg.myapp I/AWSIotMqttManager: Auto-resubscribe is enabled. Resubscribing to previous topics. 2020-12-14 13:45:48.585 23999-24408/com.myorg.myapp I/iot: mqtt connect: Connected 2020-12-14 13:45:48.585 23999-24408/com.myorg.myapp D/iot: iot connected 2020-12-14 13:45:48.591 23999-24408/com.myorg.myapp W/AWSIotMqttManager: connection is Lost 2020-12-14 13:45:48.592 23999-24408/com.myorg.myapp I/AWSIotMqttManager: schedule Reconnect attempt 3 of 10 in 32 seconds. 2020-12-14 13:45:48.594 23999-24408/com.myorg.myapp I/iot: mqtt connect: Reconnecting

To Reproduce The code is based on the [former] example from:

mqtt = AWSIotMqttManager(UUID.randomUUID().toString(), endpoint)
        mqtt.setCleanSession(true);
        mqtt.setAutoReconnect(true);
        mqtt.setKeepAlive(60);

        mqtt.connect(
            KeyStoreInfo.clientKeyStore, object : AWSIotMqttClientStatusCallback {
                override fun onStatusChanged(
                    status: AWSIotMqttClientStatusCallback.AWSIotMqttClientStatus?,
                    throwable: Throwable?
                ) {
                    Log.i("iot", "mqtt connect: " + status.toString())
                    when (status) {
                        AWSIotMqttClientStatusCallback.AWSIotMqttClientStatus.Connected -> {
                            // THIS NEEDS TO RUN ON UI THREAD
                            Toast.makeText(this@MainActivity, "MQTT Connected", Toast.LENGTH_SHORT).show()
                        }
                    }
                }
            })

Which AWS service(s) are affected? AWSIot

Expected behavior Expectation is that the device remains connected to MQTT.

Environment Information (please complete the following information):

Additional context

I'm not sure if this is an Android issue or SDK issue. There is a possibly that Android would be trying to conserve battery and put the thread/app to sleep and lose the TCP/IP connection

armandr commented 3 years ago

Update:

So the issues seems to be that if the onStatusChanged closure throws an exception, it will drop the MQTT connection.

Not sure if this is the intended behaviour or the exception should be escalated instead.

TheSunFish commented 3 years ago

I also encountered such a problem, repeatedly disconnected and reconnected inexplicably.

eeatonaws commented 2 years ago

When AWSIotMqttManager.connect(…) is called, a try/catch block is executed where the connection status callback provided to AWSIotMqttManager.connect(…) is invoked, followed by calling connect(…) on the MQTT client. When the code in the try block fails, it goes into a catch block for MqttException or Exception. When the connection status callback fails, the catch block for Exception is executed, which sets the connection state to Disconnected. The connection status callback could fail for any number of reasons, since it is defined by the developer, meaning we cannot determine if the error that caused the connection status callback to fail warrants disconnecting the client. To prevent the MQTT client from disconnecting when an error occurs in the connection status callback, you could place your implementation of the connection status callback in a try/catch and handle any potential error based on your implementation.

eeatonaws commented 2 years ago

Closing due to inactivity. Please create a new issue if you have additional questions.