You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 09:22:04