【问题标题】:How can I publish a file using Mosquitto in python?如何在 python 中使用 Mosquitto 发布文件?
【发布时间】:2013-10-22 17:11:10
【问题描述】:

我正在使用 python-mosquitto 订阅支持文件类型上传的 MQTT 代理。从命令行上的 Mosquitto 使用 -f 标志时,我可以很好地使用它。但是,我不知道如何使用 client.publish(topic, payload) 从我的 python 脚本中指定要发布的文件。

当我尝试向 Python mosquitto 扔一些奇怪的东西时,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 不会引发错误,但代理没有正确接收文件。有什么想法吗?

谢谢!!

【问题讨论】:

    标签: python mqtt


    【解决方案1】:

    必须同时发布整个文件,因此您需要读入整个文件并一次性发布。

    以下代码有效

    #!/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)
    

    【讨论】:

      【解决方案2】:

      值得注意的是,这是 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()
      

      【讨论】:

      • 两个答案都有效,事实证明这是我的代码中缺少client.loop_forever() 和大量的 byteArray 转换都运行良好。对我来说很奇怪,我能够发布像“hello world”这样的文本而不需要永远循环,但是在处理文件(大约 70k)时它需要loop_forever()。感谢您的帮助!
      猜你喜欢
      • 1970-01-01
      • 2016-06-23
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      • 1970-01-01
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多