3

My paho-mqtt service is unable to reconnect to broker in case connection is lost.
On connection lost I pinged both broker from the Android Client using adb shell and Android device from the server (Windows 10) hosting mosquito broker.
I connected to network using LAN via my Raspberry Pi 3B having deployed Android Things (latest version). The LAN network is quite stable. For Paho MQTT I am using latest version.
I have noticed that my MQTT connection is lost at random.

fun connect(context: Context) {
    connectOptions.keepAliveInterval=30//seconds
    connectOptions.mqttVersion = MqttConnectOptions.MQTT_VERSION_3_1_1
    connectOptions.isAutomaticReconnect = true
    connectOptions.isCleanSession = false

    connectOptions.setWill(Global.HmiSrNo + "_out", "Disconnected".toByteArray(), 2, false)
    mqttAndroidClient = MqttAndroidClient(context, serverUri, clientId)
    try {
        val token = mqttAndroidClient.connect(connectOptions)
        token.actionCallback = object : IMqttActionListener {
            override fun onSuccess(asyncActionToken: IMqttToken)
            {
                subscribe(context)
                automicLight.set(true)
                issnackbarshown = true
                if(Global.connectivitylost)
                    wantToCloseDialog = true

            }
            override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) {
                //connectionStatus = false
                Log.i("Connection", "failure")
                // Give your callback on connection failure here
                exception.printStackTrace()
            }
        }
    } catch (e: MqttException) {
        // Give your callback on connection failure here
        e.printStackTrace()
    }
 }

Build.Grade

<service android:name="org.eclipse.paho.android.service.MqttService" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.things.permission.USE_PERIPHERAL_IO" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
repositories {
    maven {
        url "https://repo.eclipse.org/content/repositories/paho-releases/"
    }
}
Dark Sorrow
  • 1,681
  • 14
  • 37
  • Does this answer your question? [MQTT Paho Client not reconnect automatically to broker on Android Service](https://stackoverflow.com/questions/53305445/mqtt-paho-client-not-reconnect-automatically-to-broker-on-android-service) – Sniffer Oct 18 '21 at 12:06
  • 1
    @Sniffer I looked into the solution provided before posting question; however as suggested in the solution I have made `connectOptions.isAutomaticReconnect = true` yet I am unable to reconnect. – Dark Sorrow Oct 18 '21 at 12:09
  • What is shown in the logs after the initial disconnect? Do you see any evidence it's trying to reconnect? – hardillb Oct 18 '21 at 12:42
  • @hardillb Their was no evidence of reconnect nor any exception. – Dark Sorrow Oct 18 '21 at 13:16
  • It may be due to your OS not allowing the app to run in background and shutting the whole app and MQTT connection also. – global_warming Jun 06 '22 at 16:21

1 Answers1

-1

The following is JAVA so you will need the kotlin conversions.

Without the error message it will be hard to debug. Override "connectionLost(Throwable cause)" from the MqttCallback interface. This will give you the error reason.

In my applications I implement both the IMqttActionListener and MqttCallback in a single class. Track whether the app called disconnect or was disconnected for another reason. If the app did not call disconnect Restart the connection process. One of the most common reasons I've seen in the past is Context is null which closes the connection and will not allow connection to restart. If using AndroidViewModel you can use the application context which should live longer than Activity Context.

public class Pg3MqttDelegate implements IMqttActionListener, MqttCallback {

....



/////////////////////// IMqttActionListener /////////////////////////////
////////////////////////////////////////////////////////////////////////

@Override
public void onSuccess(IMqttToken asyncActionToken) {
    Log.v(LOG_TAG, "onSuccess: " + asyncActionToken);
    viewModel.setMqttConnected(true);
}

@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
    viewModel.setError(ErrorObject.getInstance("" + exception));
    Log.v(LOG_TAG, "onFailure: " + exception + ", " + asyncActionToken.getException());
}



/////////////////////////// MqttCallback ///////////////////////////////
////////////////////////////////////////////////////////////////////////


@Override
public void connectionLost(Throwable cause) {
    Log.v(LOG_TAG, "connection lost: " + cause);
    viewModel.setMqttConnected(false);
}

@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
    Log.v(LOG_TAG, "Id:" + message.getId() + ", message topic:" + topic +  ", message:" + message.toString());

    ....

}

@Override
public void deliveryComplete(IMqttDeliveryToken token) {
    //triggered when publish is completed
    try {
        Log.v(LOG_TAG, "deliveryComplete token:" + token.getMessage());
    } catch (MqttException e) {
        Log.v(LOG_TAG, "could not log deliveryComplete message");
    }
}
Javier Refuerzo
  • 274
  • 3
  • 7