1

我希望能够在 Quart 中使用 WebSocket 来接收发送的任何消息,并发送我可能需要发送的任何消息。无法保证消息会在发送和接收之间交替。

例如,Quart 的 WebSockets 教程页面包含以下代码片段:

@app.websocket('/api/v2/ws')
@collect_websocket
async def ws(queue):
    while True:
        data = await queue.get()
        await websocket.send(data)

不知何故,我想修改while True循环中的代码,以便我可以检查是否有任何数据要接收,但如果没有,我将改为检查队列。

我希望只有在有东西要接收的情况下才能在套接字上等待接收(如果方法中有timeout参数,这可能可以实现receive),但这不是一个选项。

那么,如何await在更新的同时使用 WebSocket 进行await更新呢?

4

1 回答 1

2

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)()
)
于 2020-03-18T02:08:13.597 回答