Hello
I implemented my own mqtt client using your lib. We need a JWT as a token to connect or reconnect. So I’m using an asynchronous call to fetch a token when connecting or reconnecting.
In the logs I see the following lines:
- “Try to reconnect in 5s”.
- “Disconnected. Source=CLIENT Cause=‘com.hivemq.client.mqtt.exceptions.ConnectionClosedException: Timeout while waiting for PINGRESP’ Reconnect=true”
So the callback was triggered. But nothing happened afterwards. And as my app is trying to publish messages constantly, I see that the client is neither connected nor trying to in the logs:
WARN RxComputationThreadPool-17 b.i.t.c.m.MQTTConnection - Publishing message to topic=event failed!
java.util.concurrent.CompletionException: com.hivemq.client.mqtt.exceptions.MqttClientStateException: MQTT client is not connected.
So my question is: Is an async call allowed in onDisconnect()?
Here is my implementation:
.addDisconnectedListener(context → TypeSwitch.when(context).is(Mqtt5ClientDisconnectedContext.class, this::onDisconnect)) //
private void onDisconnect(final Mqtt5ClientDisconnectedContext context) {
LOG.info(“Disconnected. Source={} Cause=‘{}’ Reconnect={}”, context.getSource(), context.getCause(), Boolean.toString(!terminated));
hasDisconnected = true;
if (terminated) {
LOG.info(“Graceful disconnect by user. Will not try to reconnect again!”);
return;
}
LOG.info(“Try to reconnect in {}s”, Integer.toString(RECONNECT_PERIOD_IN_SECONDS));
buildMqttConnector() //
.thenAccept(mqttConnector → context.getReconnector() //
.reconnect(!terminated) //
.connect(mqttConnector) //
.delay(RECONNECT_PERIOD_IN_SECONDS, TimeUnit.SECONDS));
}
private CompletableFuture buildMqttConnector() {
return mqttConfig.getPasswordSupplier().get() //
.thenApply(password → Mqtt5Connect.builder() //
.cleanStart(true) //
.sessionExpiryInterval(NO_SESSION) //
.simpleAuth() //
.username(mqttConfig.getUsername()) //
.password(password.getBytes(StandardCharsets.UTF_8)) //
.applySimpleAuth() //
.restrictions() //
.sendMaximum(INFLIGHT_MAX_VALUE) //
.applyRestrictions() //
.build());
}
public Supplier<CompletableFuture> getPasswordSupplier() {
return this.passwordSupplier;
}