如何在Python中使用asyncio.wait\u for运行\u直到\u完成以同步调用异步方法

2024-09-21 03:19:57 发布

您现在位置:Python中文网/ 问答频道 /正文

要允许超时通过Pythonwebsocket接收数据,FAQ: How do I set a timeout on recv()?建议使用异步接收数据:

await asyncio.wait_for(websocket.recv(), timeout=10)

由于我接收数据的函数不是异步的,因此我调整了this answer以运行asyncio循环,直到接收到数据或发生超时:

loop.run_until_complete(asyncio.wait_for(ws.recv(), timeout=10))

不幸的是,此语句似乎无效,因为出现以下异常:

An asyncio.Future, a coroutine or an awaitable is required

对我来说,asyncio.wait_for似乎不是run_until_complete的有效参数,尽管documentation清楚地显示了一个await适用于它的示例

我在这里遗漏了什么?在同步方法中使用asyncio.wait_for的正确方法是什么


Tags: 方法runasynciofortimeoutawaitdohow
2条回答

您需要为loop.run_until_complete提供一个协同程序。为此,您可以将接收代码包装到异步函数中:

async def receive_message():
    return await asyncio.wait_for(ws.recv(), timeout=10)

loop.run_until_complete(receive_message())

下面是一个完整的工作代码:

import asyncio
import websockets

URI = "ws://0.0.0.0:8765"
TIMEOUT = 2

async def create_ws():
    return await websockets.connect(URI)

async def receive_message():
    ws = await create_ws()
    print("Connected")
    message = await asyncio.wait_for(ws.recv(), timeout=TIMEOUT)
    print(f"Received message in less than {TIMEOUT} seconds: {message}")

if __name__ == "__main__":
    asyncio.get_event_loop().run_until_complete(receive_message())

Python中有两个常见的websocket模块。 虽然websockets是用import websockets导入的,但也有websocket-client是用import websocket导入的

这两个模块提供几乎相同的API,其中ws.recv()允许接收数据

这些模块彼此如此相似的事实可能会导致混淆,这至少会导致我的异常

虽然websockets能够进行异步操作,但websocket却不能。这意味着我的声明

loop.run_until_complete(asyncio.wait_for(ws.recv(), timeout=10))

仅适用于websockets,如果与websocket一起使用,则例外

An asyncio.Future, a coroutine or an awaitable is required

将会发生

相关问题 更多 >

    热门问题