首页 > 解决方案 > Python中如何使用asyncio.wait_for到run_until_complete同步调用async方法

问题描述

为了允许通过 Python websocket接收数据超时,FAQ: How do I set a timeout on recv()? 推荐使用异步接收数据:

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

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

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

不幸的是,该声明似乎无效,因为发生了以下异常:

需要 asyncio.Future、协程或 awaitable

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

我在这里缺少什么 -asyncio.wait_for在同步方法中使用的正确方法是什么?

标签: pythonwebsocketasync-awaitpython-asynciopython-multithreading

解决方案


您需要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())

推荐阅读