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

MQTT脚本可订阅主题但无法发布数据且无报错,是否函数顺序有误?

问题分析与修复方案

你的代码存在多个问题,导致无法发布数据,不止是函数调用顺序的问题:

1. 回调函数绑定顺序错误

你先调用了client.connect(),之后才绑定on_connect等回调函数。虽然loop_forever()会处理后续逻辑,但连接完成时的on_connect回调可能无法被正确触发(你这里订阅正常是因为后续loop补全了逻辑,但这属于不规范写法)。正确顺序应该是先绑定所有回调函数,再调用connect。

2. on_publish回调函数完全错误

paho.mqtt官方定义的on_publish回调签名为:

def on_publish(client, userdata, mid):
    # mid是发布消息的ID,用于跟踪发布状态
    pass

而你定义的on_publish参数完全不符合规范,还在函数内递归调用自己,这不仅无法触发发布,还会导致逻辑混乱。这个回调的作用是消息发布成功后的通知函数,并非发起发布的入口。

3. 缺少主动发起发布的逻辑

你的代码只有订阅相关逻辑,没有任何主动调用client.publish()发送数据的代码,自然不会有数据发布出去。


修复后的代码示例

import paho.mqtt.client as mqtt

broker = "broker"                   # Broker地址
port = 1883                         # Broker端口
user = "user"                       # 连接用户名
psw = "psw"                         # 连接密码
pubtopic = 'pubtopic'
subtopic = 'subtopic'

# 先定义所有回调函数
def on_connect(client, userdata, flags, rc):
    print("连接返回码: " + str(rc))
    client.subscribe(subtopic)
    # 连接成功后可在此发起首次发布,也可在其他逻辑中调用
    client.publish(pubtopic, "首次发布的测试数据")

def on_message(client, userdata, msg):
    print(f"{msg.topic} {str(msg.payload)}")
    # 示例:收到订阅消息后触发发布
    client.publish(pubtopic, f"收到消息后回复: {str(msg.payload)}")

def on_publish(client, userdata, mid):
    print(f"消息发布成功,消息ID: {mid}")

# 创建客户端实例
client = mqtt.Client("Python")
client.username_pw_set(user, psw)

# 绑定回调函数(此步骤必须在connect之前)
client.on_connect = on_connect
client.on_message = on_message
client.on_publish = on_publish

# 连接Broker
client.connect(broker, port, 60)

# 启动消息循环
client.loop_forever()

关键修正点说明

  • 调整执行顺序:先定义回调→绑定回调→连接Broker,确保所有回调在连接前完成注册。
  • 修正on_publish的签名,还原其作为发布成功通知的作用。
  • 添加了主动发布的示例:在on_connect中发起首次发布,还在on_message中添加了"收到订阅消息后触发发布"的逻辑,你可根据需求调整发布触发时机。

内容的提问来源于stack exchange,提问作者rspari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 09:42:05