Python paho-mqtt接收MQTT消息如何打印发送端客户端名称
解答
首先明确一个容易踩的误区:on_message回调的第一个入参client是你当前运行的订阅端自己的客户端实例,对应的ID是你初始化时传入的Smartphone,不是消息发送方的客户端,没法从这里拿到发送者名称。
另外核心协议限制:MQTT 3.1/3.1.1 版本的标准PUBLISH报文,本身不携带发布端的客户端ID/名称字段,原生message对象只包含主题、载荷、QoS、保留标记这几个属性,没法直接从消息元数据里拿到发送方信息。
你可以根据自己的场景选下面两种可行方案实现需求:
方案1:载荷携带发送方标识(兼容性最好,无Broker依赖)
这是最通用的实现方式,要求所有往STATE主题发消息的客户端,发布消息时把自身名称写进载荷里,最常见的是用JSON格式约定载荷结构:
{ "client_name": "温湿度传感器01", "data": "温度26.5℃,湿度45%" }
对应修改你的订阅端代码,解析载荷拿发送方即可:
import json import paho.mqtt.client as mqtt import time def on_message(client, userdata, message): payload_raw = message.payload.decode("utf-8") try: payload = json.loads(payload_raw) msg = payload.get("data", payload_raw) sender = payload.get("client_name", "未携带标识的客户端") except json.JSONDecodeError: msg = payload_raw sender = "未知客户端(消息格式不匹配)" print(f"received message: {msg} from: {sender}") mqttBroker = "localhost" client = mqtt.Client("Smartphone") client.connect(mqttBroker) client.loop_start() client.subscribe("STATE") client.on_message = on_message time.sleep(180) client.loop_stop()
方案2:MQTT 5.0 用户属性传参(不改动原有载荷结构)
如果你用的MQTT Broker支持MQTT 5.0协议,可以让发布端把客户端名称作为消息的用户属性附加,不需要修改原有载荷的内容结构:
- 发布端发消息时附加属性示例:
from paho.mqtt.properties import Properties from paho.mqtt.packettypes import PacketTypes publish_props = Properties(PacketTypes.PUBLISH) publish_props.UserProperty = ("client_name", "温湿度传感器01") # 发布时传入属性 client.publish("STATE", "温度26.5℃,湿度45%", properties=publish_props) - 订阅端在回调里读取属性拿发送方:
def on_message(client, userdata, message): msg = message.payload.decode("utf-8") sender = "未知客户端" if hasattr(message, "properties") and message.properties.UserProperty: for k, v in message.properties.UserProperty: if k == "client_name": sender = v break print(f"received message: {msg} from: {sender}")
不要尝试通过Broker日志、订阅系统主题的方式拿发送方,这类方案依赖特定Broker的实现,兼容性极差,生产环境不建议用。
内容的提问来源于stack exchange,提问作者White Man
相关产品推荐
相关产品推荐

