在python asyncio websockets库中,该示例调用run_forever()
。为什么要这样做?
run_until_complete()
是否应该阻止并运行websockets循环?
#!/usr/bin/env python
# WS server example
import asyncio
import websockets
async def hello(websocket, path):
name = await websocket.recv()
print(f"< {name}")
greeting = f"Hello {name}!"
await websocket.send(greeting)
print(f"> {greeting}")
start_server = websockets.serve(hello, "localhost", 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
# if you comment out the above line, this doesn't work, i.e., the server
# doesn't actually block waiting for data...
如果我注释掉run_forever(),程序将立即结束。
start_server
是库等待返回的。为什么run_until_complete
不足以使其在hello()
上被阻止/等待?
答案 0 :(得分:0)
websockets.serve
只需启动服务器并立即退出。 (它仍然需要等待,因为配置服务器可能需要网络通信。)因此,您需要实际运行事件循环。
由于服务器被设计为无限期运行,因此无法通过将协程传递给run_until_complete
来以通常的方式运行事件循环。由于服务器已经启动,因此没有协程可以运行,您只需要让事件循环运行并完成其工作即可。这是run_forever
有用的地方-它告诉事件循环无限期地运行(执行先前计划的任务,例如属于服务器的任务),或者直到调用loop.stop
使其停止为止
在Python 3.7和更高版本中,应该使用asyncio.run
运行asyncio代码,这将创建一个新的事件循环,因此上述技巧将不起作用。在现代异步代码中完成上述操作的一个好方法是使用serve_forever
方法(未经测试):
async def my_server():
ws_server = await websockets.serve(hello, "localhost", 8765)
await ws_server.server.serve_forever()
asyncio.run(my_server())