我正在使用 websockets
库在 Python 3.4 中创建一个 websocket 服务器。这是一个简单的回显服务器:
import asyncio
import websockets
@asyncio.coroutine
def connection_handler(websocket, path):
while True:
msg = yield from websocket.recv()
if msg is None: # connection lost
break
yield from websocket.send(msg)
start_server = websockets.serve(connection_handler, 'localhost', 8000)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
假设我们 - 另外 - 想要在某些事件发生时向客户端发送消息。为简单起见,让我们每 60 秒定期发送一条消息。我们该怎么做?我的意思是,因为 connection_handler
一直在等待传入的消息,服务器只有在收到来自客户端的消息 后 才能采取行动,对吗?我在这里错过了什么?
也许这种情况需要一个基于事件/回调的框架而不是一个基于协程的框架? 龙卷风?
原文由 weatherfrog 发布,翻译遵循 CC BY-SA 4.0 许可协议
TL;DR 使用
asyncio.ensure_future()
同时运行多个协程。不,您不需要任何其他框架。异步应用程序与同步应用程序的整体思想是它在等待结果时不会阻塞。它是如何实现的,使用协程或回调并不重要。
在同步应用程序中,您将编写类似
msg = websocket.recv()
的内容,这将阻止整个应用程序,直到您收到消息(如您所述)。但是在异步应用中就完全不同了。当你做
msg = yield from websocket.recv()
你说这样的话:暂停执行connection_handler()
直到websocket.recv()
会产生一些东西。在协程中使用yield from
将控制返回给事件循环,因此可以执行其他一些代码,同时我们正在等待websocket.recv()
的结果。请参阅 文档 以更好地了解协同程序的工作原理。在执行 启动事件循环 的阻塞调用之前,您可以使用
asyncio.async()
运行任意数量的协程。这是一个示例客户端实现。它要求您输入名称,从回显服务器接收它,等待来自服务器的另外两条消息(这是我们的定期消息)并关闭连接。
要点:
asyncio.async()
重命名为asyncio.ensure_future()
。