Docker环境下MQTT订阅端用户名密码未识别问题排查
问题分析与解决
核心问题点
1. 密码文件权限不足
容器内的Mosquitto服务默认以mosquitto用户运行,你通过mosquitto_passwd生成的passwd.txt文件大概率属于root用户,且权限设置严格,导致Mosquitto进程无法读取密码文件,直接引发认证失败。
2. 订阅端代码的回调未绑定+循环逻辑冲突
- 你定义了
on_connect和on_message回调函数,但未将它们绑定到MQTT客户端实例上,导致连接成功后不会自动执行订阅操作,也无法触发消息接收回调。 - 同时调用
client.loop_start()和client.loop_forever(),这两个函数均用于处理MQTT网络事件,同时使用会造成逻辑冲突,引发连接异常。
3. 主题不匹配(次要问题)
发布端发布的主题是Temp,但订阅端on_connect函数里订阅的是/Temp,这两个是完全不同的MQTT主题,即便认证成功也无法收到消息。
4. 发布端代码的矛盾点
你的Mosquitto配置明确设置了allow_anonymous false,但发布端代码未添加用户名密码认证却能正常运行,说明要么容器未重启导致配置未生效,要么你实际测试的发布端代码已补充认证逻辑。
解决步骤
步骤1:修复密码文件权限
进入Mosquitto容器,修改密码文件的所属用户和权限:
docker exec -it mqtt bash chown mosquitto:mosquitto /mosquitto/config/passwd.txt chmod 600 /mosquitto/config/passwd.txt exit
然后重启容器使配置生效:
docker-compose restart mqtt
步骤2:修正订阅端代码
调整代码,绑定回调函数,修复循环逻辑,统一主题:
import paho.mqtt.client as mqtt username='user' password='passwd' def on_message(client, userdata, message): print("[SUB] received message: %s" % message.payload.decode("utf-8")) def on_connect(client, userdata, flags, rc): print("[SUB] Connected with result code "+str(rc)) # 订阅与发布端一致的主题 client.subscribe("Temp") mqtt_broker = "localhost" client = mqtt.Client("sub") ttl = 120 client.username_pw_set(username, password) # 绑定回调函数到客户端实例 client.on_connect = on_connect client.on_message = on_message client.connect(mqtt_broker, 1883, ttl) print("[SUB] Awaiting notifications") # 只保留一个循环处理函数 client.loop_forever()
步骤3:修正发布端代码(必做)
既然开启了认证,发布端必须添加用户名密码认证才能正常连接:
import paho.mqtt.client as mqtt import time def on_publish(client,userdata,result): print("[PUB] Data published = %s" % result) mqtt_broker ="localhost" client = mqtt.Client("test") client.on_publish = on_publish # 添加认证信息 client.username_pw_set("user", "passwd") client.connect(mqtt_broker, 1883) for i in range(10): temp = i client.publish("Temp", temp) print("[PUB] Just published %.4f to topic Temp" % temp) time.sleep(1)
内容的提问来源于stack exchange,提问作者user2399453
相关产品推荐
相关产品推荐

