将MQTT主题和消息放入数组中
我对Python完全是个新手,对MQTT的了解也非常基础。
我想写一个Python脚本,订阅一个通配符主题,然后建立一个这个通配符下的主题列表。我知道MQTT协议本身不支持这个功能,所以我得通过Python来实现。我在想把主题和消息放在一个数组里。
我有以下这些主题:
/weather/current/temperature
/weather/current/humidity
/weather/current/pressure
/weather/current/time
在我的Python脚本中,我订阅的是 /weather/current/#。
比如,我想象中的数组可能是这样的:
[/weather/current/temperature,message]
[/weather/current/humidity,message]
[/weather/current/pressure,message]
[/weather/current/time,message]
我的脚本基本上是一个标准的例子,我尝试了几种方法来实现这个功能,但都没有成功。我觉得我最大的问题是对on_message这个函数的理解不够。这个函数是针对所有主题执行一次,还是每个主题执行一次呢?
def on_connect(mqttc, obj, rc):
print("rc: "+str(rc))
def on_message(mqttc, obj, msg,):
# print(msg.topic+" "+str(msg.payload))
payload = str(msg.payload)
print(msg.topic+" Payload -> "+payload)
def on_publish(mqttc, obj, mid):
print("mid: "+str(mid))
def on_subscribe(mqttc, obj, mid, granted_qos):
print("Subscribed: "+str(mid)+" "+str(granted_qos))
def on_log(mqttc, obj, level, string):
print(string)
try:
mqttc = mqtt.Client("Python-MQTT-Sub")
mqttc = mqtt.Client()
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
# Uncomment to enable debug messages
#mqttc.on_log = on_log
mqttc.connect("localhost", 1883, 60)
mqttc.subscribe("/weather/current/#", 0)
mqttc.loop_forever()
except KeyboardInterrupt:
print("\ninterrupt received, exiting...")
2 个回答
on_message
是在收到来自消息代理的消息时被调用的。这些消息可以是你订阅的任何主题的内容,比如说 /weather/current
及其以上的主题。虽然你只用了一次订阅,但每条消息都是独立的事件。
还有一个小建议 - 通常不建议把客户端 ID 写死在代码里,除非你把 clean session
设置为 false。如果客户端 ID 重复,你会被从消息代理断开连接。要么自己生成一个独特的 ID,要么在调用 Client()
时不指定客户端 ID,这样系统会自动生成一个随机的 ID。
最后一点 - 除非有特别的原因,否则其实没有必要在主题前加斜杠。前面的斜杠会增加一个额外的层级,第一层是一个空字符串。这可能和你预想的有些不同,所以在某些情况下会让人感到困惑。
正如@ralight上面所说,on_message
是在收到消息时被调用的(这条消息可能是保留消息,也可能不是)。为了说明这一点,我稍微修改了你的代码,添加了一个叫topic_names
的数组,这个数组会随着消息的到来而被填充。
import paho.mqtt.client as mqtt
topic_names = []
def on_message(mqttc, obj, msg,):
# print(msg.topic + " " + str(msg.payload))
payload = str(msg.payload)
print(msg.topic + " Payload -> " + payload)
topic_names.append(msg.topic)
try:
mqttc = mqtt.Client()
mqttc.on_message = on_message
mqttc.connect("localhost", 1883, 60)
mqttc.subscribe("weather/current/#", 0)
mqttc.loop_forever()
except KeyboardInterrupt:
print "Received topics:"
for topic in topic_names:
print topic
运行这个程序并向它发布两条消息后,会显示
weather/current/temp Payload -> Fair
weather/current/humidity Payload -> 10
^C
weather/current/temp
weather/current/humidity