我是python的新手,具有非常基本的MQTT知识。
我正在尝试编写一个订阅通配符主题的python脚本,然后在通配符下构建主题列表。我知道MQTT协议不适合这个,所以我需要通过python实现这一点。我正在考虑将主题和消息放在一个数组中。
我有以下主题:
/天气/电流/温度
/天气/电流/湿度
/天气/电流/压力
/天气/电流/时间
在我的python脚本中,我订阅了/ weather / current /#.
例如,我想数组就是这样的:
[/天气/电流/温度,消息
[/天气/电流/湿度,消息
[/天气/电流/压力,消息
[/天气/电流/时间,消息
我的脚本几乎是标准示例,我尝试了几种方法来实现这一点,但失败了。我认为我的根本问题是我对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...")
答案 0 :(得分:2)
正如@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
答案 1 :(得分:1)
on_message
。这可能是您订阅的任何主题的消息,因此任何/weather/current
及更高版本。即使您只使用了一个订阅,消息也是所有不同的事件。
另一个小问题 - 除非您将clean session
设置为false,否则对客户端ID进行硬编码通常不是一个好主意。重复的客户端ID会导致您与代理断开连接。要么自己生成一些独特的东西,要么在Client()
的调用中保留client_id,然后使用默认值None
,这意味着客户端ID是随机生成的。
最后一件事 - 除非你有其他理由这样做,否则没有真正需要使用前导斜杠启动主题。前导斜杠实际上添加了额外的层次结构,第一级是空字符串。这并不完全是你所期望的,所以在某些情况下会令人困惑。