我正在使用MQTT docker-compose环境,并尝试在订阅者中使用用户名和密码。没有密码,发布和订阅都可以正常工作。
我docker-compose。Yml看起来像这样:
version: "3"
services:
mqtt:
image: eclipse-mosquitto:latest
container_name: mqtt
network_mode: bridge
ports:
- 1883:1883
volumes:
- ./conf:/mosquitto/config
- ./log:/mosquitto/log
容器上/mosquito/to/config/目录下的mosquito .conf如下所示:
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
listener 1883
allow_anonymous false
password_file /mosquitto/config/passwd.txt
我的密码文件在/mosquito/config/passwd.txt中,有一行用户名和明确的密码。我进入容器,找到文件所在的位置,并执行
mosquitto_passwd -U /mosquitto/config/passwd.txt
将文件就地加密。当我查看passwd。txt时它有一个加密文本条目:
用户:7 101美元vOlxOuwvzHmJiYWC N8MKHb4fczMZNPzCBfXK4k7mUbOp美元+ PzwT2Yb4IeU1KMKABP8hOsvDjqe + DcK7q6ksVuGmdODfWjrjQNAfJMjZw = =
当我运行发布时,它工作正常。如下所示:
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.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)
但是订阅永远不会收到它:
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.connect(mqtt_broker, 1883, ttl)
client.loop_start()
client.subscribe("Temp")
print("[SUB] Awaiting notifications")
client.loop_forever()
在日志中我看到未经授权的错误:
1670429277: New connection from 172.17.0.1:59538 on port 1883.
1670429277: Client mac disconnected, not authorised.
有什么问题吗?
根据评论,在这种情况下的问题是你的"发布";没有设置用户名和密码(但您在订阅代码中设置了)。在测试时使用已知的好程序(例如mosquitto_sub
/mosquitto_pub
)是值得的(否则你可能在订阅和发布代码中都有bug,这会使调试变得混乱!)我将留下我的答案的其余部分,以防它对其他人有所帮助。
我已经能够运行你的代码成功后作出一些调整。这可能不是一个完整的答案,因为我还没有能够复制你的问题,但可以指向你的代码,工作。
我在你的代码中看到的主要问题是你没有配置client
来使用你的回调。例如:
client.on_message = on_message
client.on_connect = on_connect
这意味着您的程序将不订阅(并且不会对收到的任何消息做任何事情)。
除了上面的,你同时使用线程和阻塞循环函数。这将导致问题,因为您最终会运行多个网络循环实例。我修复了这些问题,并做了一些其他的小改动:
import paho.mqtt.client as mqtt
import time
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")
time.sleep(5)# Allow time for mosquitto to startup
mqtt_broker = "mqtt"
client = mqtt.Client("sub")
client.on_message = on_message
client.on_connect = on_connect
ttl = 120
client.username_pw_set(username, password)
client.connect(mqtt_broker, 1883, ttl)
#client.loop_start() # Pick either threaded or non-threaded, not both!
client.subscribe("Temp")
print("[SUB] Awaiting notifications")
client.loop_forever()
我运行你的代码和蚊子使用docker -配置如下(如果需要,很高兴添加Dockerfile
等):
version: '3.4'
services:
mqtt:
image: eclipse-mosquitto:latest
ports:
- "1883:1883"
volumes:
- ./conf:/mosquitto/config
- ./log:/mosquitto/log
pythondocker:
image: pythondocker
build:
context: .
dockerfile: ./Dockerfile
我在主机上使用mosquitto_pub.exe -h 127.0.0.1 -u user -P passwd -t Temp -m "foo"
发送一条消息,该消息被成功接收。
Attaching to pythondocker-mqtt-1, pythondocker-pythondocker-1
pythondocker-pythondocker-1 | [SUB] Awaiting notifications
pythondocker-pythondocker-1 | [SUB] Connected with result code 0
pythondocker-pythondocker-1 | [SUB] received message: foo
如果我修改python,将密码更改为passwd2
,那么我确实得到了你所看到的错误(不确定为什么你会得到这个-我正在使用你提供的passwd.txt
):
1670453773: New connection from 172.26.0.2:40037 on port 1883.
1670453773: Client sub disconnected, not authorised.