Python Paho MQTT: невозможно немедленно опубликовать функцию

Я реализую программу, которая слушает определенную тему и реагирует на нее, когда мой ESP8266 публикует новое сообщение. Когда от ESP8266 будет получено новое сообщение, моя программа вызовет обратный вызов и выполнит ряд задач. Я публикую два сообщения в моей функции обратного вызова в тему, которую слушает Arduino. Однако сообщения публикуются только после выхода из функции.

Спасибо за все ваше время заранее.

Я попытался использовать цикл (1) с тайм-аутом 1 секунду внутри функции обратного вызова. Программа немедленно опубликует сообщение, но, похоже, оно застряло в цикле. Сможет ли кто-нибудь дать мне несколько советов, как я могу немедленно выполнить каждую функцию публикации в моей функции обратного вызова, а не после завершения всего обратного вызова и возврата к основному циклу loop_forever()?

import paho.mqtt.client as mqtt
import subprocess
import time

# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    client.subscribe("ESP8266")

# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
    print(msg.topic+" "+str(msg.payload))
    client.publish("cooking", '4')
    client.loop(1)
    print("Busy status published back to ESP8266")
    time.sleep(5)
    print("Starting playback.")
    client.publish("cooking", '3')
    client.loop(1)
    print("Free status published published back to ESP8266")
    time.sleep(5)
    print("End of playback.")


client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect("192.168.1.9", 1883, 60)
#client.loop_start()

# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()

person Zen    schedule 01.05.2016    source источник


Ответы (1)


Вы не можете этого сделать, вы уже находитесь в цикле обработки сообщений (это то, что называется функцией on_message) в момент, когда вы вызываете публикацию. Это поставит исходящие сообщения в очередь для обработки следующей итерацией цикла, поэтому они отправляются после возврата on_message.

Он зависает, когда вы вызываете метод цикла, потому что цикл уже запущен.

В любом случае вы не должны делать блокирующие (спящие) вызовы в обратном вызове on_message, если вам нужно сделать что-то, что требует времени, запустите для этого второй поток. Делая это, вы освобождаете сетевой цикл для обработки исходящих публикаций, как только они будут сделаны.

person hardillb    schedule 01.05.2016
comment
Вы также не должны вызывать loop() в обратном вызове. - person ralight; 02.05.2016
comment
Спасибо за ваш ответ. Я очень ценю это! Я думаю, что меня немного смутила цель обратного вызова on_message. - person Zen; 08.05.2016