Terminating Connection Attempts

If automatic reconnect is enabled, how can I terminate the connection if the client is attempting to connect to a manually entered incorrect server Uri? Is there a client.close() method or something similar?

Hi Rich,

There is a disconnect() method in the async MQTTClient, check it out: hivemq-mqtt-client 1.3.0 javadoc (com.hivemq)

I hope this helps?
Kind regards,
Dasha from HiveMQ Team

The disconnect() method only works once the client is connected. I need to stop the connect process if automatic reconnect is enabled, and incorrect server ip address or authorisation details are entered. In this event the client tries to connect indefinitely. How do I halt this process in order for correct parameters to be re-entered?

There does not appear to be a method to stop the process in this event. (Unless I close down the App and restart)

Hi Rich,

Here is an example, how to influence the client reconnecting, I hope this will be helpful:

package com.hivemq.client.mqtt.examples;

import com.hivemq.client.mqtt.lifecycle.MqttClientDisconnectedContext;
import com.hivemq.client.mqtt.lifecycle.MqttClientDisconnectedListener;
import com.hivemq.client.mqtt.lifecycle.MqttDisconnectSource;
import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient;
import com.hivemq.client.mqtt.mqtt5.Mqtt5Client;
import com.hivemq.client.mqtt.mqtt5.message.auth.Mqtt5SimpleAuth;

import java.time.LocalTime;
import java.util.concurrent.atomic.AtomicInteger;

public class ReconnectStopper {

    private static final String MQTT_SERVER     = "WRONG-HOSTNAME-ADDRESS.s2.eu.hivemq.cloud";
    private static final int MQTT_PORT     = 8883;
    private static final String  MQTT_USERNAME     = "USER";
    private static final String  MQTT_PASSWORD     = "PASSWORD";

    public static void main(final String[] args) throws InterruptedException {
        test();
    }

    private static void test() {

        AtomicInteger counter = new AtomicInteger();
        final int LIMIT = 10;

        final Mqtt5SimpleAuth simpleAuth = Mqtt5SimpleAuth.builder()
                .username(MQTT_USERNAME)
                .password(MQTT_PASSWORD.getBytes())
                .build();

        final String  clientIdentifier = LocalTime.now().toString().replaceAll("\\W+", "");
        System.out.println("My Client Id: " + clientIdentifier);
        final Mqtt5AsyncClient mqtt5AsyncClient = Mqtt5Client.builder().identifier(clientIdentifier)
                .serverHost(MQTT_SERVER)
                .serverPort(MQTT_PORT)
                .sslWithDefaultConfig()
                .simpleAuth(simpleAuth)

                .addDisconnectedListener(new MqttClientDisconnectedListener() {
                    @Override
                    public void onDisconnected(MqttClientDisconnectedContext context) {

                        // server disconnected the client
                        if (context.getSource() == MqttDisconnectSource.SERVER) {
                            System.out.println("server disconnected the client " + LocalTime.now());
                            counter.incrementAndGet();
                        }

                        // client disconnected itself f.e. unknown host)
                        if (context.getSource() == MqttDisconnectSource.CLIENT) {
                            System.out.println("client disconnected itself f.e. unknown host " + LocalTime.now());
                            counter.incrementAndGet();
                        }

                        int attemptCounter = counter.get();
                        System.out.println("it was attempt#"+attemptCounter+" of " + LIMIT + ".");
                        if (counter.get() > LIMIT) {
                            System.out.println("NOT reconnecting again.");
                            context.getReconnector().reconnect(false);
                        } else {
                            System.out.println("Will reconnect again.");
                            context.getReconnector().reconnect(true);
                        }
                    }
                })
                .addConnectedListener(context -> System.out.println("connected " + LocalTime.now()))
                .addDisconnectedListener(context -> System.out.println("disconnected " + LocalTime.now()))
                .buildAsync();
        System.out.println("Starting the connect().");
        mqtt5AsyncClient.connect();
    }
}

Kind regards,
Dasha from HiveMQ Team

Hi Dasha,

I have solved the problem using a similar method to that described in a previous Topic: “Cancel automatic reconnects” !

I will have a read through your example code in your last reply too to see if there are alternative solutions to this as well.

Thanks
Rich

Hi Rich,

Thank you for the update! You are right - it is also using the context.getReconnector().reconnect(false); to stop the client reconnecting.

Kind regards,
Dasha from HiveMQ Team

Yes, I’m now using context.getReconnector().reconnect(false); etc. To stop the automatic reconnects when neccessary. Seems to work OK.

Thanks.

I have also added .addConnectedlistener(context …etc… with a boolean variable cancelReconnect= false;

On initial build I have set cancelReconnect= true; etc … This means that auto-reconnect is initially disabled and only becomes enabled after initially connecting successfully to a server. This solves the problem of endless re-connect attempts if the initial server Ip is entered incorrectly by a user etc
… Would be good to include a means of enabling/disabling auto-reconnect directly.

Hi Rich,

Thanks for your feedback, if the default reconnect strategy does not match your use case, you can implement your own strategy, like described in this article: HiveMQ MQTT Client Features: Reconnect Handling

Kind regards
Dasha from HiveMQ Team

Thanks for this additional information. My use case now works very well, so everything is finally OK!

Connection attempts also stop if, when using the Async Client, you call cancel on the CompletableFuture that is returned by the connect method. Probably the Rx Client has something similar, although I haven’t looked into it.