【问题标题】:Python Paho/MQTT : Detecting Connect errorPython Paho/MQTT:检测连接错误
【发布时间】:2017-07-16 00:58:06
【问题描述】:

简而言之,我有一个运行良好的 Paho/MQTT 样本集,但我无法检测到错误。具体来说,我没有收到 on_connect 回调,并且当给出无效的 UserID/Pswd 组合时,它会静默失败。 事实上,从各种迹象来看,一切都很好!

我做错了什么?

(snip)

def on_connect(client, userdata, flags, rc):
    print("Connected with flags [%s] rtn code [%d]"% (flags, rc) )

def on_disconnect(client, userdata, rc):
    print("disconnected with rtn code [%d]"% (rc) )

def on_publish(client, userdata, msgID):
    print("Published with MsgID [%d]"% (msgID) )


mqttc = mqtt.Client()
mqttc.on_connect = on_connect
mqttc.on_disconnect = on_disconnect
mqttc.on_publish = on_publish

mqttc.username_pw_set(Q_USER, Q_PSWD)

rc=mqttc.connect(Q_BROKER, Q_PORT)
print "Return="+str(rc)

mqttc.loop_start()
rc=mqttc.publish(Q_TOPIC, "Hello, World!")
print "Return="+str(rc)

mqttc.disconnect()
mqttc.loop_stop()

UserID 或 Pswd 故意错误时的输出:

Return=0
Published with MsgID [1]
Return=(0, 1)
disconnected with rtn code [0]

【问题讨论】:

  • 增加混乱...如果我在 connect() 调用之前移动 loop_start(),则消息无法正确发布。仍然没有错误提示
  • 您使用的是哪个代理,您是如何配置身份验证的?例如如果 mosquitto 是 allow_anonymous 是真的?
  • 请注意,在 connect() 调用之前的 loop_start() 已知会产生未定义的结果。
  • 在 python 中使用 paho-mqtt 时,除了 on_conenct 回调 rc 参数之外,有没有办法找出与 MQTT 代理的连接是否成功?

标签: python mqtt paho


【解决方案1】:

原来是几个不同的问题。

  • 首先,Connect 在没有真正连接的情况下返回。在接收到 Connect 回调之前添加一个带有 Sleep 的等待循环是至关重要的。只有回调告诉您连接成功或失败。
  • 其次,一旦我看到返回码,我发现我的协议版本不匹配失败。我的 Pi 拉下的 Mosquitto 版本真的很旧。找到一个帖子,将我的系统指向更新的版本。解决了版本不匹配问题。
  • 第三,在Connect前添加“loop_start()”不起作用。直觉的地方不是正确的地方。
  • 第四,需要在断开连接之前添加 Sleep() 调用,否则您将看不到所有回调。

最重要的是,虽然文档展示了如何使用 API,但它们并没有向您展示如何编写用于生产用途的健壮程序。

我仍在寻找方法来了解所有进行中的发布调用何时已清除,而不是使用盲睡眠调用,但我最初的问题已解决。

【讨论】:

  • 您是否能够生成工作代码来获取状态代码?
【解决方案2】:

当您发送 mqtt CONNECT 数据包时,您应该收到 CONNACK 响应。此响应包含以下代码
0 - 成功,连接接受
1 - 连接被拒绝,协议错误
2 - 被拒绝,客户端 ID 错误
3 - 拒绝,服务不可用 4 - 被拒绝,用户名或密码错误
5 - 拒绝,未授权
如您所见,您的响应应该是 4。但它是。可能是您的代理未检查凭据,因此您的 connect 消息被接受。客户端看起来不错。

【讨论】:

  • 注意 1) 我根本没有看到连接响应 2) 我使用的 QOS 为 '0' 所以连接从未成功,因为我发送为即发即弃, RC 将始终为“0”。一旦我提高了 QOS 级别,我就会收到消息发送错误。此外,一旦我成功处理了回调,我看到我收到了“1”的连接错误(旧的 Mosquitto 版本不支持 3.11 客户端协议版本)
【解决方案3】:

尝试像这样将publish 放入while 循环中

while True:
    mqttc.loop()
    rc=mqttc.publish(Q_TOPIC, "Hello, World!")
    print("Return=" + str(rc))
    if sth:
        break
mqttc.disconnect()

这样,回调函数就可以在程序结束之前执行。

【讨论】:

  • 我是 MQTT 新手,但对我来说,这会重复发布相同的消息。什么是“某事”?答案似乎是在寻找 on_publish 以使其通过。
  • 这里我的意思是如果你不将publish 放入while 循环中,程序将在触发回调函数之前终止。 sth 在这里表示任何有助于控制循环的条件。其实我记得我也遇到过同样的情况,但是想不出解决办法。我建议你试一试。
  • 同意。请参阅我回答中的第四点。目前我使用的是睡眠,但希望有一种更强大、更准确的方式来了解所有已发布消息的处理时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
相关资源
最近更新 更多