我是所有 mqtt 的新手,作為第一個練習,我想通過持久的 mqtt 會話創建一個“郵箱”服務。激勵是一個低功耗 ESP8266 設備,它大部分時間都處于睡眠狀態,并定期喚醒并檢查是否有任何待處理的命令。我嘗試使用 python 和 paho mqtt 在我的 Linux 主機上通過發送者和接收者來實現它。Mosquitto 作為代理在后臺運行。首先是“mbox”發件人,它會在每次按下 Enter 時發送另一條消息。import paho.mqtt.client as mqtt broker_address='127.0.0.1'client = mqtt.Client('MBoxClient') client.connect(broker_address)counter = 1while True: print('Press Enter to send msg #'+str(counter)+': ', end='') if input().startswith('q'): break client.publish("mbox/mail","Hello "+str(counter), qos=1) counter += 1client.disconnect()print('done!')這是我的 mbox 接收器:import paho.mqtt.client as mqttimport timedef on_message(client, userdata, message): print("message:", message.topic + ': ' + str(message.payload.decode("utf-8")))print('I\'m listening for mbox messages!')broker_address="127.0.0.1"client_name='mbox'is_first=Truewhile 1: client = mqtt.Client(client_name, clean_session=is_first) is_first=False print("polling") client.on_message=on_message client.connect(broker_address) client.subscribe('mbox/#',qos=1) client.loop_start() time.sleep(0.1) # How long should this time be? client.loop_stop()# client.loop(0.1) # why doesn't this do the same action as the previous three lines? client.disconnect() time.sleep(5)盡管這可行,但我覺得我的解決方案非常駭人聽聞。client.loop_start()并client.loop_stop()創建另一個線程。但是當我嘗試client.loop(0.1)這樣做時,它沒有用。所以我的問題是:是否有直接輪詢消息的方法,而不是使用的間接方法loop_start();…;loop_stop()?如果 usingloop_start();time.sleep(t);loop_end()是慣用的,我怎么知道要睡多久?loop(0.1); instead of 為什么在我執行loop_start()時接收器不工作;睡眠(0.1);循環停止()`?有什么不同?接收方是否保證收到所有消息?有沒有更好的方法來實現這種模式?
1 回答

慕婉清6462132
TA貢獻1804條經驗 獲得超2個贊
問題按順序回答。
不,輪詢完全違背了像 MQTT 這樣的發布/訂閱協議的意義
你真的應該
client.loop()
在一個循環中調用,它默認只在提供的超時期限內處理 1 個數據包。QOS 1 需要多個數據包才能完成傳送。調用
client.loop(0.1)
將阻塞 0.1 秒以等待傳入消息,然后返回。如果消息在 0.1 秒后到達,它將駐留在操作系統 TCP/IP 堆棧中,直到您client.loop()
再次調用。如果您沒有定期調用它,那么代理將啟動客戶端,因為 KeepAlive 測試將失敗??蛻舳搜h還處理發送所有訂閱消息。假設消息在 QOS > 0 時發布并且您已在 QOS > 0 時訂閱并且客戶端 ID 保持不變并且干凈會話為 false 代理應該在訂閱者離線時傳遞和發布消息
如前所述,您需要
client.loop()
為每條消息調用多次,因為每個喚醒周期您只調用一次。啟動后臺線程將在您讓它運行的時間長度內處理所有必需的消息。
添加回答
舉報
0/150
提交
取消