调用msg.topic致MQTT客户端on_message方法失效,求问题原因及解决
问题分析与解决
嘿,我一眼就揪出问题所在了——你在on_message回调里不小心覆盖了原始的MQTT消息对象!
问题根源
看这段出问题的代码:
def on_message(client, userdata, msg): msg = msg.payload.decode() # 这里把原始msg对象直接覆盖成字符串了! print("topic:", msg.topic) # 现在msg是字符串,根本没有topic属性! print("Received Message: {}".format(msg))
原始的msg是paho-mqtt库提供的消息对象,它自带.topic(消息主题)和.payload(字节流形式的消息内容)两个核心属性。但你第一行代码把msg重新赋值成了解码后的字符串,后面再尝试访问msg.topic时,本质是在调用字符串的topic属性——这肯定会触发AttributeError!
那为啥程序没报错?因为paho-mqtt的客户端循环(比如你用的loop_forever())会自动捕获回调里的异常,不会让整个程序崩溃,但会直接终止当前回调的执行,这就是你看到“后续打印语句不再执行”的原因。
修复方案
只需要换个变量名,别覆盖原始的msg对象就行:
import paho.mqtt.client as client hostname = 'iot.eclipse.org' topic = 'Mein/Topic' def on_message(client, userdata, msg): payload = msg.payload.decode() # 用新变量存解码后的内容 print("topic:", msg.topic) # 现在能正常访问原始msg的topic属性了 print("Received Message: {}".format(payload)) def on_connect(client, userdata, flags, rc): print("Connection returned result: " + str(rc) + "\n") if rc == 0: print("Listening now.\n") client.subscribe(topic) client = client.Client() client.on_message = on_message client.on_connect = on_connect client.connect(hostname) client.loop_forever()
小提醒
在回调函数里操作传入的参数时,尽量别直接覆盖原始对象,尤其是这种库提供的带多属性的对象,很容易因为变量名重复踩这种隐性坑。
内容的提问来源于stack exchange,提问作者Philipp
相关产品推荐
相关产品推荐

