ESP32使用PubSubClient接收MQTT消息时断开连接问题排查
问题结论
这个问题绝大多数情况下是业务代码配置问题,并非PubSubClient官方库本身的缺陷。
核心原因排查方向
- ClientID冲突:你的代码里ESP32连接MQTT broker使用的ClientID固定为
php,如果你的Java订阅端或者其他客户端也使用了相同的ClientID,MQTT broker会按照协议规则踢掉旧的同ID连接,这就会导致ESP32刚完成订阅就被断开,自然收不到PUBLISH类型的报文,只能正常处理心跳响应报文。 client.loop()调用不及时:你没有贴出主loop()函数的代码,如果主循环里存在长时间的delay()阻塞逻辑,没有高频调用client.loop()处理MQTT报文,就会导致订阅报文、发布报文的处理被延后,甚至触发心跳超时断开连接。- 订阅未实际生效:你在代码里打印了
subscribe方法的返回值,如果该值为false说明订阅请求被broker拒绝,常见原因是你使用的user账号没有sms主题的订阅权限,或者broker端主题配置异常。 - 报文超出缓冲区限制:PubSubClient默认的最大报文缓冲区为256字节,如果你接收的MQTT消息长度超过该值,会导致报文解析出错,无法识别出PUBLISH类型的报文,甚至直接触发连接断开。
修复步骤
- 修改ESP32的ClientID为唯一值,比如基于ESP32的MAC地址生成动态ID,不要和其他客户端共用相同的ClientID。
- 调整主
loop()函数逻辑,移除长时间的阻塞操作,确保client.loop()被高频调用。 - 查看订阅返回值,如果返回
false先检查MQTT账号的主题权限,也可以用第三方MQTT桌面工具使用相同账号密码订阅sms主题测试,排除broker配置问题。 - 如果接收的消息长度超过256字节,修改PubSubClient库头文件中
MQTT_MAX_PACKET_SIZE的配置,调大到大于你最大消息长度的数值。
内容的提问来源于stack exchange,提问作者Kamshory
相关产品推荐
相关产品推荐

