Java MQTT5客户端运行数小时后报无法发布:客户端未连接错误如何解决
问题原因分析
- 未开启自动重连机制:当前使用的HiveMQ MQTT客户端默认不开启自动重连,运行过程中如果出现网络波动、服务端主动断开空闲连接等情况,客户端断开后不会自动重建连接,发布消息时就会抛出Not able to publish: MQTT client is not connected错误。
- 未配置心跳保活参数:代码中未设置
keepAliveInterval参数,MQTT broker会默认将长时间无消息交互的客户端判定为失活,主动断开连接释放资源。 - 缺少连接状态监听:没有配置断连事件回调,无法及时感知连接中断,也无法做针对性的异常处理。
修复方案
直接修改连接方法的构造逻辑,补充必要参数配置即可,修改后代码如下:
public Mqtt5AsyncClient connect(String host, int port) { Mqtt5AsyncClient client = MqttClient.builder().useMqttVersion5() .identifier(UUID.randomUUID().toString()) .serverHost(host) .serverPort(port) // 新增:配置60秒心跳间隔,可根据实际业务调整 .keepAliveInterval(60) // 新增:开启自动重连,初始重连间隔1秒,最大间隔2分钟 .automaticReconnect() .initialDelay(1) .maxDelay(120) .applyAutomaticReconnect() // 新增:配置连接监听回调,可自行添加日志、业务告警逻辑 .addDisconnectedListener(context -> { logger.debug("MQTT客户端断开连接,原因:{}", context.getCause().getMessage()); }) .addConnectedListener(context -> { logger.debug("MQTT客户端连接成功"); }) .buildAsync(); Mqtt5ConnAck connectionAck = null; try { connectionAck = client.toBlocking().connect(); Mqtt5ConnAckReasonCode connAckCode = connectionAck.getReasonCode(); logger.debug("Client connected to broker with url: " + host + ":" + port + " ::Connection ack code: " + connAckCode + " keep alive 60s"); } catch (Exception ex) { logger.debug("Not able to connect to broker with url: " + host + ":" + port); ex.printStackTrace(); } return client; }
额外注意事项
- 如果业务要求消息不丢失,建议同时配置
cleanStart(false)和会话过期时间,断连重连后可以恢复之前的未完成消息传输。 - 发布消息时建议添加回调监听,出现发送失败的情况可以根据返回的错误码做降级处理,比如本地缓存消息待连接恢复后补发。
内容的提问来源于stack exchange,提问作者NewbieCoder
相关产品推荐
相关产品推荐

