簡體   English   中英

使用 Paho Mqtt 客戶端在 on_message 中發布不工作

[英]Publish in on_message with Paho Mqtt Client not working

main 方法中的發布調用不會向代理發送消息,而是返回 (0,2)。 on_publish 不會被調用。 我不知道我應該如何看待錯誤在哪里。 我嘗試了 qos=2 並運行主要方法 async 但它沒有修復它。 基本連接工作,因為 on_message 被調用。 mqtt-server 也適用於其他項目。 有人有什么想法嗎?

import paho.mqtt.client as mqtt
import subprocess
import shutil
import os
import glob
import logging
from datetime import datetime
import RPi.GPIO as GPIO
import time
from multiprocessing import Pool
GPIO.setmode(GPIO.BCM)

direction = 19
pwm = 26
GPIO.setup(direction, GPIO.OUT)
GPIO.setup(pwm, GPIO.OUT)

pwm = GPIO.PWM(pwm,19000)
speed = 0
pwm.start(speed)
running = False

client = mqtt.Client()
#First: pip3 install paho-mqtt
print("Starte Listener")

def start():
    GPIO.output(direction, GPIO.LOW)
    for dc in range(10, 40, 1):
        speed = dc 
        pwm.ChangeDutyCycle(speed)
        time.sleep(0.25)

def end():
    GPIO.output(direction, GPIO.LOW)
    for dc in list(reversed(range(0,40,1))):
        speed = dc 
        pwm.ChangeDutyCycle(speed)
        time.sleep(0.5)


def main(mqttClient):
    print("Started Spinning")
    running = True
    start()
    print(mqttClient.publish("scanner","shoot"))
    print("Waiting 124 seconds")
    time.sleep(124)
    print("ending spinning")
    end()
    print("finished spinning")
    running = False 

def on_connect2(client, userdata, flags, rc):
    client.subscribe("scanner",2)
    print("Connected "+str(rc))
    

# The callback for when a PUBLISH message is received from the server.
def on_message(mqttClient, userdata, msg):
    print("Recived message: "+str(msg.payload,'UTF-8'))
    if(str(msg.payload,'UTF-8') == "spin" and running == False):
        main(mqttClient)

def disconnected():
    print("Disconneted")

def on_publish(self, client, userdata, mid):
    print("onPublish")
    print(client,userdata,mid)

logger = logging.getLogger(__name__)
client.enable_logger(logger)

client.on_connect = on_connect2
client.on_message = on_message
client.on_publish = on_publish
client.on_disconnect = disconnected
client.username_pw_set("....","....")
client.connect("gx1", 1883,60)
client.loop_forever()

作為快速修復,我創建了一個新客戶端:

def main(mqttClient):
    print("Started Spinning")
    running = True
    start()
    mq = mqtt.Client("shot_idicator")
    mq.username_pw_set("...","...")
    mq.connect("gx1", 1883,60)
    mq.publish("scanner","shoot")
    mq.disconnect()
    mq = None
    print("Waiting 124 seconds")
    time.sleep(124)
    print("ending spinning")
    end()
    print("finished spinning")
    running = False 

現在它可以工作了,但我認為這不是應該這樣做的。

這是因為您正在阻塞 MQTT 客戶端線程。

當您調用client.loop_forever()時,它會接管進程主線程並使用它來處理所有 MQTT 通信。 當收到一條新消息時,MQTT 客戶端線程從網絡堆棧中提取它並轉換為消息 object,然后傳遞給on_message()回調。 這個 function 在客戶端線程上運行。

當你調用client.publish()這將做兩件事之一

  1. 如果消息是 QOS 0 並且小於網絡 MTU,它將發布消息。
  2. 如果消息的 QOS 為 1 或 2 或大於網絡 MTU,那么它將排隊等待由客戶端線程處理的消息。

代碼中的問題*是您將main()的返回阻止了 124 秒,這反過來又阻止了on_message() function 的返回,因此客戶端線程無法發布您的消息。

如果你想做一些需要很長時間或阻塞on_message() (或任何回調函數)的事情,你應該啟動一個單獨的線程來運行它們。

*理論上,您的消息看起來應該屬於上面列出的情況 1,但可能還有其他因素導致它排隊)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM