1
votes

I am using the HiveMQ MQTT client in Spring to receive MQTT messages.

My client configuration looks like this

public Mqtt3AsyncClient mqtt3Client() {
    var mqtt3Client = Mqtt3Client.builder()
            .serverHost("my.host")
            .sslWithDefaultConfig()
            .serverPort(0000)
            .automaticReconnectWithDefaultConfig()
            .buildBlocking();

    mqtt3Client.connect();
    return mqtt3Client.toAsync();
}

After the client is available, another Spring Bean is initialized using the client. It subscribes a topic:

@PostConstruct
public void subscribeTopic() {
    mqtt3AsyncClient.subscribeWith()
            .topicFilter("topicfilter")
            .qos(MqttQos.AT_LEAST_ONCE)
            .callback(message -> {
                /*Handle message*/
            })
            .send()
            .whenComplete((mqtt3SubAck, throwable) -> {
                if (throwable != null) {
                    /*Logging*/
                } else {
                    /*Logging*/
                }
            });
}

I saw multiple times that no more messages were delivered to my application while I was still able to use the client connection to send messages (thus it was connected at that time).

I could not find any documentation on how the HiveMQ MQTT client handles the configured automaticReconnectWithDefaultConfig(). Can anyone point out, whether my subscription created in subscribeTopic() is resubscribed? I also found the method addSubscription() that may replace the .topicFilter(..).qos(...) part. I also could no find any information whether this makes the subscription more resilient to connection losses.

I'd appreciate any kind of information on that topic.

Thanks.

1

1 Answers

3
votes

Currently the HiveMQ MQTT Client will only continue to receive messages for subscriptions if the broker reports an existing session in the ConAck of the re-connect. This requires two things - 1) you need to set cleanSession = false when initially connecting, and 2) the broker needs to have not lost the session in between connections.

For 1) you can try adding this to your connect:

client.connectWith().cleanSession(false).send();

With 2) it will depend on the broker and what the cause of the connection loss was. If it was 'just' a network outage and the broker was running normal in the background then it should work fine. If the broker crashed and was restarted, then it will require that the broker has persistence configured and that it was able to re-establish the session after the restart.

There are actually a couple of discussions over on the github project page of the HiveMQ MQTT Client regarding this issue and whether functionality should be added to auto re-subscribe even in the case that no pre-existing session was found. And also on a related note whether any publishes done while the connection was lost should auto-publish even if no session was found after the re-connect. If these are features you require, maybe hop on over there and chime in on the discussions :)

Lastly, you can also manually perform re-subscribes by adding a MqttClientConnectedListener while building the client which can then re-create the subscriptions each time the auto re-connect happens.

HTH
Cheers,
C