在Python中处理异步

在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

我来自一个节点,在这个节点上处理异步设计就像添加回调一样简单,然后开始您的生活。我正在尝试用python编写一些应用程序,但我没有获得同样的成功,我正在努力寻找要搜索的内容,因为似乎没有直接的等价物

下面是一个示例,其中我正在运行MQTT消息传递客户端并等待来自传感器的状态更改信号

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库。一个又一个。