无法在Python中接收所有MQTT消息

时间:2017-12-09 08:15:04

标签: python mqtt

我正在尝试使用MQTT将消息从一个python脚本发送到另一个。一个脚本是发布者。第二个脚本是订阅者。我每0.1秒发送一次消息。

出版商:

client = mqtt.Client('DataReaderPub')
client.connect('127.0.0.1', 1883, 60)
print("MQTT parameters set.")

# Read from all files
count = 0
for i in range(1,51):
    payload = "Hello world" + str(count)
    client.publish(testtopic, payload, int(publisherqos))
    client.loop()
    count = count+1
    print(count, ' msg sent: ', payload)
    sleep(0.1)

订户:

subclient = mqtt.Client("DynamicDetectorSub")
subclient.on_message = on_message
subclient.connect('127.0.0.1')

subclient.subscribe(testtopic, int(subscriberqos))

subclient.loop_forever()

mosquitto broker version - 3.1

mosquitto.conf的最大飞行消息设置为0,持久性为真。

出版商QOS = 2

订户QOS = 2

两个脚本中的

topic ='test'

当我在同一个脚本中运行订阅者和发布者时,将按预期发送和接收消息。但是当它们处于不同的脚本中时,我没有收到所有消息,有时也没有消息。我首先运行订阅者然后运行发布者。我已经尝试使用loop.start()和loop.stop()等用户等待几分钟。

我无法调试此问题。任何指针都会很棒!

编辑:

  1. 我在发布后包含了client.loop()。 - >与之前相同的输出
  2. 当我在'on_connect'和'on_disconnect'中打印语句时,我注意到客户端mqtt连接已建立并几乎立即断开连接。这种情况每秒都会发生我甚至得到了这个消息 -

    [WinError 10053]已建立的连接已被主机中的软件中止

  3. 保持活力= 60

    我应该看一下其他参数吗?

3 个答案:

答案 0 :(得分:1)

您还需要在发布者中调用网络循环函数,以便客户端实际获得一些时间来执行IO(以及QOS2的双握手)。

在客户端调用client.loop()后添加client.publish()

import paho.mqtt.client as mqtt
import time

client = mqtt.Client('DataReaderPub')
client.connect('127.0.0.1', 1883, 60)
print("MQTT parameters set.")

# Read from all files
count = 0
for i in range(1,51):
    payload = "Hello world" + str(count)
    client.publish("test", payload, 2)
    client.loop()
    count = count+1
    print(count, ' msg sent: ', payload)
    time.sleep(0.1)

订阅者代码:

import paho.mqtt.client as mqtt

def on_message(client, userdata, msg):
  print(msg.topic + " " + str(msg.payload))

subclient = mqtt.Client("DynamicDetectorSub")
subclient.on_message = on_message
subclient.connect('127.0.0.1')

subclient.subscribe("test", 2)

subclient.loop_forever()

答案 1 :(得分:0)

当我运行您的代码时,订阅者经常错过最后一个数据包。我无法重现你描述的问题。

如果我改写这样的发布者......

from time import sleep
import paho.mqtt.client as mqtt

client = mqtt.Client('DataReaderPub')
client.connect('127.0.0.1', 1883, 60)
print("MQTT parameters set.")

client.loop_start()

# Read from all files
count = 0
for i in range(1,51):
    payload = "Hello world" + str(count)
    client.publish('test', payload, 2)
    count = count+1
    print(count, ' msg sent: ', payload)
    sleep(0.1)

client.loop_stop()
client.disconnect()

...然后我再也看不到丢弃的数据包了。我在这里使用start_loop / stop_loop方法,它们异步运行mqtt循环。我不确定究竟是什么原因导致丢弃的数据包,但我怀疑当代码退出时,最终消息仍在发布者的发送队列中。

答案 2 :(得分:0)

原来这是一个愚蠢的错误。 正如hardillb建议我查看了经纪人日志。它表明订户客户端已经连接。 很长一段时间后我都在使用Pycharm。因此,我不小心对发布者和订阅者进行了多次运行,以至于他们在输出控制台中并行运行。难怪他们断开连接,因为客户端ID是相同的。抱歉,添麻烦了。发布后不需要BTW client.loop()。谢谢hardillb。