在Python中处理异步
我来自一个节点,在这个节点上处理异步设计就像添加回调一样简单,然后开始您的生活。我正在尝试用python编写一些应用程序,但我没有获得同样的成功,我正在努力寻找要搜索的内容,因为似乎没有直接的等价物 下面是一个示例,其中我正在运行MQTT消息传递客户端并等待来自传感器的状态更改信号在Python中处理异步,python,multithreading,asynchronous,blocking,Python,Multithreading,Asynchronous,Blocking,我来自一个节点,在这个节点上处理异步设计就像添加回调一样简单,然后开始您的生活。我正在尝试用python编写一些应用程序,但我没有获得同样的成功,我正在努力寻找要搜索的内容,因为似乎没有直接的等价物 下面是一个示例,其中我正在运行MQTT消息传递客户端并等待来自传感器的状态更改信号 import paho.mqtt.client as mqtt from ouimeaux.environment import Environment from ouimeaux.signals import re
import paho.mqtt.client as mqtt
from ouimeaux.environment import Environment
from ouimeaux.signals import receiver, statechange
def on_connect(client, userdata, rc):
print('Connected with result code '+str(rc))
client.subscribe('lights/#')
def turn_lights_on(client, userdata, rc):
for (x, value) in enumerate(devices['switches']):
devices['switches'][x].on()
def turn_lights_off(client, userdata, rc):
for (x, value) in enumerate(devices['switches']):
devices['switches'][x].off()
def reply_with_devices(client, userdata, rc):
for (x, value) in enumerate(devices['switches']):
client.publish('devices/new', switches[x])
for (x, value) in enumerate(devices['motions']):
client.publish('devices/new', motions[x])
def on_switch(switch):
print "Switch found: ", switch.name
devices['switches'].append(switch)
def on_motion(motion):
print "Motion found: ", motion.name
devices['motions'].append(motion)
client = mqtt.Client("wemo_controller")
client.on_connect = on_connect
client.message_callback_add('lights/on', turn_lights_on)
client.message_callback_add('lights/off', turn_lights_off)
client.message_callback_add('devices/discover', reply_with_devices)
client.connect('localhost', 1883, 60)
print 'Running WEMO controller - listening for messages on localhost:1883'
devices = { 'switches': [], 'motions': [] }
env = Environment(on_switch, on_motion)
env.start()
env.discover(seconds=3)
switch = env.get_switch('Desk lights')
@receiver(statechange)
def motion(sender, **kwargs):
print 'A THING HAPPENED'
print "{} state is {state}".format(sender.name, state="on" if kwargs.get('state') else "off")
env.wait()
client.loop_forever()
这两个库似乎都有自己的方法来支撑线程,但似乎我一次只能有一个阻塞和侦听。我有一种感觉,线程可能是答案,但我正在努力解决如何实现这一点,不确定它是否正确。我也很困惑wait()和loop_forever()实际上是做什么的
我要寻找的答案是解决这个问题的“python”方法。您可能想看看 “Twisted是一个用Python编写的事件驱动网络引擎” 它是专门为构建异步网络应用程序而设计的
特别是,最近python中已经集成了异步编程,请阅读,并使用来注册回调。所以 如果您使用的是python 3.3,那么python提供了一个专门用于此目的的内置库(以前称为“Tulips”)。 如果您使用的是Python2.7,那么您可以使用Asyncio的后端口。如果没有什么适合您的,那么您显然可以使用其他答案中建议的成熟的网络编程框架。我是使用Python API的MQTT代理/客户端库的作者 客户端API不需要任何回调。您可以使用客户端API订阅某个主题,然后运行循环以读取和处理传入消息。比如:
import asyncio
from hbmqtt.client import MQTTClient
C = MQTTClient()
@asyncio.coroutine
def test_coro():
yield from C.connect(uri='mqtt://localhost/', username=None, password=None)
# Adapt QOS as needed
yield from C.subscribe([
{'filter': 'lights/on', 'qos': 0x01},
{'filter': 'lights/off', 'qos': 0x01},
{'filter': 'devices/discover', 'qos': 0x01},
])
while some_condition:
# Wait until next PUBLISH message arrives
message = yield from C.deliver_message()
if message.variable_header.topic_name == 'lights/on':
# Lights on
elif message.variable_header.topic_name == 'lights/off':
# Lights off
yield from C.acknowledge_delivery(message.variable_header.packet_id)
yield from C.disconnect()
if __name__ == '__main__':
loop=asyncio.get_event_loop()
loop.run_until_complete(test_coro())
HBMQTT仍在开发中。它需要Python3.4。作为参考,Node从Twisted中获得了灵感。Python有一些框架提供类似节点的行为:
Twisted
(如前所述),并且从3.4版开始就内置在Python中。看起来有一个(文档记录不良的)MQTT库。一个又一个。