与外部 MQTT 代理连接的问题

问题描述

我在 Pine A64+ 1Gb 上使用 Ubuntu mate,我用 python3 安装了 paho mqtt 库,我通过创建本地蚊子服务器测试了库,它工作正常。现在我需要连接到具有用户名和密码的外部代理,我尝试使用以下代码,但它对我不起作用。有了这个,我什至无法连接到代理。

import paho.mqtt.client as mqtt
import time
broker_address = "121.242.232.175.xip.io"
port = 1883

def on_connect(client,userdata,flags,rc):
    if rc==0:
        client.connected_flag = True
        print("connected OK Returned code=",rc)
    else:
        print("Bad connection Returned code=",rc)

mqtt.Client.connected_flag = False

client = mqtt.Client("SWAHVACAHU00000600")
client.username_pw_set(username="#####",password="#####")
client.on_connect = on_connect
client.loop_start()
client.connect(broker_address,port)
#while not client.connected_flag:
#   print("inthe while")
#   time.sleep(1)

client.loop_stop()
client.publish("pine","Hello from Pinr A64",0)
client.disconnect()

我正在检查 hivemqtt 用作 websocket 客户端并订阅同一主题

解决方法

再次检查 loop_start() 的作用:

这些函数实现了网络循环的线程接口。在connect*() 之前或之后调用loop_start() 一次,会在后台运行一个线程来自动调用loop()。这为其他可能阻塞的工作释放了主线程。此调用还处理与代理的重新连接。调用 loop_stop() 停止后台线程

paho-mqtt

这意味着您启动了一个线程,该线程经常处理您的所有网络操作(也发送您的连接尝试)。在您的代码中,您通过调用 loop_stop() 立即再次停止该线程 - 因此您的连接尝试很有可能甚至没有发出。

此外,您的主程序在 client.disconnect() 之后立即终止,没有任何延迟 - 因此网络线程(如果正在运行)完全没有时间处理任何事情

我建议重构您的代码,以便您的操作按时进行,并在所有工作完成后关闭连接:

def on_connect(client,userdata,flags,rc):
    if rc==0:
        print("Connected.")
        client.publish("mytopic/example","")
    else:
        print("Connection refused,rc=",rc)

def on_disconnect(client,rc):
    print ("Disconnected")
    if rc != 0:
        # otherwise loop_forever won't return
        client.disconnect()

def on_publish(client,userdataq,mid):
    print ("Message delivered - closing down connection")
    client.disconnect()


print ("Program started")

client = mqtt.Client("MyClient")
client.username_pw_set(username=user,password=pw)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.on_publish = on_publish

client.connect(broker_address,port)

client.loop_forever()

print("Program finished")

如果调用了 loop_forever(),阻塞循环 disconnect() 会自动返回。使用 loop_start() / loop_stop() 时,您需要自己的循环以防止程序终止,并且您还必须处理何时中断循环以及何时关闭网络线程。

还要考虑将 client.connect() 放在 try...except 块中