Quart 的作者在 Quart 中的Websockets帖子中回答了这个问题,其中包含一个片段,我对其稍作修改以获得以下内容:
import asyncio
from quart import copy_current_websocket_context, Quart, websocket
app = Quart(__name__)
@app.websocket('/ws')
async def ws():
async def consumer():
while True:
data = await websocket.receive()
async def producer():
while True:
await asyncio.sleep(1)
await websocket.send(b'Message')
consumer_task = asyncio.ensure_future(consumer())
producer_task = asyncio.ensure_future(producer())
try:
await asyncio.gather(consumer_task, producer_task)
finally:
consumer_task.cancel()
producer_task.cancel()
该片段创建了两个不同的异步函数,它们有自己的while True
循环。然后,Pythonasyncio.ensure_future
用于创建两个不同Task
的 s 来处理 . 最后,asyncio.gather
被调用以同时评估任务。
通过在 的定义中定义两个任务ws
,它们充当闭包,这意味着它们可以访问websocket
“特殊”全局对象,这仅在ws
函数内部有意义。如果你想在函数体之外定义这些函数ws
,可能是因为你需要从其他地方调用它们,你可以copy_current_websocket_context
在将它们传递给时使用 Quart 中的函数ensure_future
:
consumer_task = asyncio.ensure_future(
copy_current_websocket_context(consumer)()
)