Python 3.x 将paho MQTT与Python中的另一个异步IO进程相结合
我在Python中有一个基本的MQTTListener类,它侦听关于某些主题的消息,并且应该启动或停止从另一个脚本导入的异步进程。除非手动停止,否则此进程将永远运行。让我们假设侦听器如下所示:Python 3.x 将paho MQTT与Python中的另一个异步IO进程相结合,python-3.x,asynchronous,mqtt,Python 3.x,Asynchronous,Mqtt,我在Python中有一个基本的MQTTListener类,它侦听关于某些主题的消息,并且应该启动或停止从另一个脚本导入的异步进程。除非手动停止,否则此进程将永远运行。让我们假设侦听器如下所示: import paho.mqtt.client as mqtt import json from python_file.py import async_forever_function class MqttListener: def __init__(self, host, port, cl
import paho.mqtt.client as mqtt
import json
from python_file.py import async_forever_function
class MqttListener:
def __init__(self, host, port, client_id):
self.host = host
self.port = port
self.client_id = client_id
self.client = mqtt.Client(client_id=self.client_id)
self.client.connect(host=self.host, port=self.port)
def on_connect(self, client, userdata, flags, rc):
self.client.subscribe(topic=[("start", 1), ])
self.client.subscribe(topic=[("stop", 1), ])
logging.info(msg="MQTT - connected!")
def on_disconnect(client, userdata, rc):
logging.info(msg="MQTT - disconnected!")
def on_message(self, client, userdata, message, ):
print('PROCESSING MESSAGE', message.topic, message.payload.decode('utf-8'), )
if message.topic == 'start':
async_forever_function(param='start')
print('process started')
else:
async_forever_function(param='stop')
print('process removed')
def start(self):
self.client.on_connect = lambda client, userdata, flags, rc: self.on_connect(client, userdata, flags, rc)
self.client.on_message = lambda client, userdata, message: self.on_message(client, userdata, message)
self.client.on_disconnect = lambda client, userdata, rc: self.on_disconnect(client, userdata, rc)
self.client.loop_start()
def stop(self):
self.client.loop_stop()
现在,这适用于启动新的异步进程。也就是说,在开始MQTT主题上发布消息时,会正确触发async_函数。但是,一旦启动此异步进程,侦听器将无法再接收/处理来自stop MQTT主题的消息,并且异步进程将永远继续运行,而实际上它本应停止
我的问题:如何调整此类的代码,使其在后台运行活动异步进程时也能处理消息?您不能在
on_message()
回调中执行阻止任务
此回调在MQTT客户端线程(由loop\u start()
函数启动的线程)上运行。此线程处理所有网络流量和消息处理,如果您阻止它,则它无法执行任何操作
如果要从
on_message()
回调调用长时间运行的任务,则需要为长时间运行的任务启动一个新线程,这样它就不会阻塞MQTT客户机循环。您不能在on_message()
回调中执行阻塞任务
此回调在MQTT客户端线程(由loop\u start()
函数启动的线程)上运行。此线程处理所有网络流量和消息处理,如果您阻止它,则它无法执行任何操作
如果要从消息()上的
调用长时间运行的任务
callback您需要为长时间运行的任务启动一个新线程,这样它就不会阻塞MQTT客户机循环。启动消息到达时,进程是否已启动
打印?编辑问题以显示输出,这样我们就可以看到发生了什么logged@hardillb很抱歉,我误读了您的评论。不,启动的流程未打印,因为async进程仍在运行。当启动消息到达时,进程已启动
是否已打印?编辑问题以显示输出,以便我们可以查看发生了什么logged@hardillb很抱歉,我误读了您的评论。不,没有打印启动的进程,因为异步进程仍在运行。我尝试通过添加另一个循环来实现您的建议,但我得到RuntimeError:无法在另一个循环运行时运行事件循环。我已尝试解决此问题,但无法解决此问题。您是否可以使用我的通用代码编辑您的答案,以显示启动新线程的含义?不,您不能运行“另一个”循环,您必须在自己的线程上运行async\u forever\u函数
。那么,解决方案是什么呢?@MarcoLettieri与之前一样。启动一个新线程来运行阻塞/长时间运行任务。我尝试通过添加另一个循环来实现您的建议,但我得到RuntimeError:在另一个循环运行时无法运行事件循环ng.我试图解决这个问题,但无法解决。您可以用我的通用代码编辑您的答案,以显示启动新线程的含义吗?不,您不能运行“另一个”循环,您必须在自己的线程上运行async\u forever\u函数
。那么,解决方案是什么呢?@MarcoLettieri与之前一样。启动一个新线程以在其上运行阻塞/长时间运行任务。