HiveMQ Java 库无法自动重新连接到代理

HiveMQ Java library fails to automatically reconnect to broker

我在我的 Java Spring 应用程序中使用 HiveMQ 库连接到 Mosquitto 实例,因为我发现它比 Paho 客户端更加用户友好。但是自动重新连接出了点问题。连接有时会丢失,应用程序无法成功重新连接(请参阅日志 1)。这也可以通过重新启动 Mosquitto 代理本身来触发(参见日志 2)。

这是我的客户端构建器代码,在断开连接时额外登录以检查凭据是否仍然正确:

        client = MqttClient.builder()
                .useMqttVersion5()
                .identifier(identifier)
                .serverHost(host)
                .serverPort(port)
                .sslWithDefaultConfig()
                // https://www.hivemq.com/blog/hivemq-mqtt-client-features/reconnect-handling/
                .automaticReconnectWithDefaultConfig()
                .addDisconnectedListener(context -> logger.error("MQTT user {} with identifier {} on {}:{} has disconnected reason: {}",
                        username, identifier, host, port, context.getCause().getMessage()))
                .buildAsync();


        client.connectWith()
                .simpleAuth()
                .username(username)
                .password(password.getBytes())
                .applySimpleAuth()
                .cleanStart(false)
                .keepAlive(60)
                .send();

1/ 在应用程序本身断开连接后,我的日志中显示了这一点:

2022-03-16 02:10:33.502 ERROR 1 --- [client.mqtt-1-2] MqttConfig : MQTT user *** with identifier SERVICE on ***:8883 has disconnected reason: Timeout while waiting for PINGRESP
2022-03-16 02:11:25.090 ERROR 1 --- [client.mqtt-1-2] MqttConfig : MQTT user *** with identifier SERVICE on ***:8883 has disconnected reason: CONNECT failed as CONNACK contained an Error Code: NOT_AUTHORIZED.
2022-03-16 02:12:27.200 ERROR 1 --- [client.mqtt-1-2] MqttConfig : MQTT user *** with identifier SERVICE on ***:8883 has disconnected reason: Timeout while waiting for CONNACK

2/ 这是代理重启后的日志,一些预期的超时,但最后也是“未授权”:

2022-03-16 10:17:37.178 ERROR 1 --- [client.mqtt-1-2] MqttConfig     : MQTT user *** with identifier SERVICE on ***:8883 has disconnected reason: Server closed connection without DISCONNECT.
2022-03-16 10:17:48.441 ERROR 1 --- [client.mqtt-1-2] MqttConfig     : MQTT user *** with identifier SERVICE on ***:8883 has disconnected reason: io.netty.channel.ConnectTimeoutException: connection timed out: ***/***:8883
2022-03-16 10:18:00.747 ERROR 1 --- [client.mqtt-1-2] MqttConfig     : MQTT user *** with identifier SERVICE on ***:8883 has disconnected reason: io.netty.channel.ConnectTimeoutException: connection timed out: ***/***:8883
2022-03-16 10:18:10.625 ERROR 1 --- [client.mqtt-1-2] MqttConfig     : MQTT user *** with identifier SERVICE on ***:8883 has disconnected reason: io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: No route to host: ***/***:8883
2022-03-16 10:18:26.845 ERROR 1 --- [client.mqtt-1-2] MqttConfig     : MQTT user *** with identifier SERVICE on ***:8883 has disconnected reason: io.netty.channel.ConnectTimeoutException: connection timed out: ***/***:8883
2022-03-16 10:18:42.584 ERROR 1 --- [client.mqtt-1-2] MqttConfig     : MQTT user *** with identifier SERVICE on ***:8883 has disconnected reason: CONNECT failed as CONNACK contained an Error Code: NOT_AUTHORIZED.

在这两种情况下,连接都会随着应用程序重新启动而恢复正常。

有什么想法吗?

您的问题似乎已在 this issue:

中得到解答

If you set the username and password on the connect call, they will not be stored and reused when the client reconnects (for security reasons).

以下代码(来自上面链接的问题)演示了该方法:

Mqtt3Client.builder()
   .identifier("ePCR mobile-" + currentTimeMillis())
   .serverHost(config.getHost())
   .serverPort(config.getPort())
   .automaticReconnectWithDefaultConfig()
   .simpleAuth()
       .username(config.getUsername())
       .password(config.getPassword())
       .applySimpleAuth()
   .buildRx();