如何在python中使用Mosquitto发布文件?

时间:2013-10-22 00:13:53

标签: python mqtt

我使用python-mosquitto订阅支持文件类型上传的MQTT代理。从命令行的Mosquitto开始,我可以使用-f标志。但是,我无法弄清楚如何使用client.publish(topic,payload)来指定在我的python脚本中执行时要发布的文件。

Python mosquitto在我尝试抛出一些奇怪的东西时给了我错误TypeError: payload must be a string, bytearray, int, float or None.。我有一个存储在本地目录中的文件,我想指定它作为发布的有效负载。

我对MQTT很有经验,但我的python非常生疏,我假设我需要在这里做一些类型的文件流功能,但不知道该怎么做。

我想在此处指定图片:mqttc.publish("/v3/device/file", NEED_TO_SPECIFY_HERE)

我试过打开图片:

    f = open("/home/pi/mosq/imagecap/imagefile.jpg", "rb")
    imagebin = f.read()
    mqttc.publish("/v3/device/file", imagebin)

但这不起作用,mqttc.publish("/v3/device/file", bytearray(open('/tmp/test.png', 'r').read()))

也没有

client.publish不会引发错误,但代理无法正确接收该文件。有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:10)

发布必须是整个文件,因此您需要阅读整个文件并一次发布。

以下代码可以使用

#!/usr/bin/python

import mosquitto

client = mosquitto.Mosquitto("image-send")
client.connect("127.0.0.1")

f = open("data")
imagestring = f.read()
byteArray = bytes(imagestring)
client.publish("photo", byteArray ,0)

可以通过

收到
#!/usr/bin/python

import time
import mosquitto

def on_message(mosq, obj, msg):
  with open('iris.jpg', 'wb') as fd:
    fd.write(msg.payload)


client = mosquitto.Mosquitto("image-rec")
client.connect("127.0.0.1")
client.subscribe("photo",0)
client.on_message = on_message

while True:
   client.loop(15)
   time.sleep(2)

答案 1 :(得分:6)

值得注意的是,这是Python 2和Python 3之间存在差异的领域之一。

Python 2 file.read()返回str而Python 3为bytesmosquitto.publish()处理这两种类型,因此在这种情况下您应该没问题,但需要注意这一点。

我已经添加了下面对@hardillb代码的一些小改进。请不要接受我的回答而不是他的回答,因为他最初写的并先到了那里!我会编辑他的答案,但我认为看到差异是有用的。

#!/usr/bin/python

import mosquitto

def on_publish(mosq, userdata, mid):
  # Disconnect after our message has been sent.
  mosq.disconnect()

# Specifying a client id here could lead to collisions if you have multiple
# clients sending. Either generate a random id, or use:
#client = mosquitto.Mosquitto()
client = mosquitto.Mosquitto("image-send")
client.on_publish = on_publish
client.connect("127.0.0.1")

f = open("data")
imagestring = f.read()
byteArray = bytes(imagestring)
client.publish("photo", byteArray ,0)
# If the image is large, just calling publish() won't guarantee that all 
# of the message is sent. You should call one of the mosquitto.loop*()
# functions to ensure that happens. loop_forever() does this for you in a
# blocking call. It will automatically reconnect if disconnected by accident
# and will return after we call disconnect() above.
client.loop_forever()