Paho Python订阅端on_message中获取MQTT发布端Client ID失败问题
在Paho Python订阅端获取MQTT发布端Client ID失败的解决方法
我需要在Paho Python订阅端获取MQTT发布端的Client ID,但当前实现无法正常工作。使用的MQTT broker是Mosquitto,客户端为Paho Python。
当前代码实现
def on_message(mqttc, obj, msg): _logger.info(msg.topic + " " + str(msg.qos) + " " + str(msg.payload) +" from "+str(mqttc._client_id))
测试情况
发布端使用Client ID "v60,v5.1,0035"发布消息,但订阅端获取到的Client ID为空值。
发布端测试日志
(mypy) taroumaru@ubuntu:~/python/paho.mqtt.python/examples $ python3 client_pub_opts.py -t group/topic1 -c "v60,v5.1,0035" 2024-08-25 13:01:38,181 __main__:131 <module> [INFO]: Connecting to localhost port: 1883 2024-08-25 13:01:38,187 __main__:139 <module> [INFO]: Publishing: {"msgnum": "0"} 2024-08-25 13:01:38,188 __main__:70 on_connect [INFO]: connect reason_code: Success 2024-08-25 13:01:38,189 __main__:78 on_publish [INFO]: mid: 1 from b'v60,v5.1,0035'
订阅端测试日志
(mypy) taroumaru@ubuntu:~/python/paho.mqtt.python/examples $ python3 client_sub_opts.py -t group/topic1 2024-08-25 13:01:34,690 __main__:135 <module> [INFO]: Connecting to localhost port: 1883 2024-08-25 13:01:34,701 __main__:69 on_connect [INFO]: reason_code: Success 2024-08-25 13:01:34,701 __main__:81 on_subscribe [INFO]: Subscribed: 1 [ReasonCode(Suback, 'Granted QoS 0')] 2024-08-25 13:01:38,189 __main__:73 on_message [INFO]: group/topic1 0 b'{"msgnum": "0"}' from b''
问题原因
当前代码中mqttc._client_id获取的是订阅端自身的Client ID,并非发布端的。如果订阅端初始化时未显式设置Client ID,Paho会自动生成,但日志中显示为空,说明订阅端未配置自身Client ID,且该方式本身无法获取发布端标识。
正确实现方式
方法1:使用MQTT 5.0消息属性(推荐)
Mosquitto和Paho Python均支持MQTT 5.0,Broker会自动将发布端的Client ID作为消息属性传递给订阅端。
修改订阅端on_message函数:
def on_message(mqttc, obj, msg): # 从MQTT 5.0属性中提取发布端Client ID publisher_client_id = msg.properties.get("ClientID", "unknown") _logger.info(f"{msg.topic} {msg.qos} {msg.payload} from {publisher_client_id}")
订阅端初始化时需指定MQTTv5协议:
import paho.mqtt.client as mqtt client = mqtt.Client(client_id="your_sub_client_id", protocol=mqtt.MQTTv5)
发布端同样需要使用MQTTv5协议发布消息,确保Broker能传递Client ID属性。
方法2:发布端将Client ID嵌入消息Payload
若无法使用MQTT 5.0,可让发布端在消息内容中携带自身Client ID:
# 发布端代码示例 import json client_id = "v60,v5.1,0035" payload = json.dumps({"msgnum": "0", "client_id": client_id}) client.publish("group/topic1", payload)
订阅端解析Payload获取Client ID:
import json def on_message(mqttc, obj, msg): payload_data = json.loads(msg.payload.decode()) publisher_client_id = payload_data.get("client_id", "unknown") _logger.info(f"{msg.topic} {msg.qos} {msg.payload} from {publisher_client_id}")
方法3:使用Mosquitto $SYS主题(仅监控场景)
Mosquitto会在$SYS/broker/connection/<clientid>/state主题发布客户端连接状态,但该方式无法直接关联到具体消息,仅适合客户端连接监控。
内容的提问来源于stack exchange,提问作者Kazuhiko Nakayama
相关产品推荐
相关产品推荐

