【问题标题】:How to use asyncio.wait_for to run_until_complete to synchronously call async method in PythonPython中如何使用asyncio.wait_for到run_until_complete同步调用async方法
【发布时间】:2021-08-03 15:40:58
【问题描述】:

为了允许通过 Python websocket 接收数据超时,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))

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

需要 asyncio.Future、协程或可等待对象

对我来说,看起来asyncio.wait_for 不是run_until_complete 的有效参数,尽管documentation 清楚地显示了一个awaits 的示例。

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

【问题讨论】:

    标签: python websocket async-await python-asyncio python-multithreading


    【解决方案1】:

    你需要给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 3.6) 编辑了我的答案。请在您的问题中添加更多代码,以便我们查看错误是否来自其他地方。
    • 是的,我能够解决问题。感谢您的帮助,这是深入挖掘这里的一个很好的提示。
    【解决方案2】:

    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 一起使用,则异常

    需要 asyncio.Future、协程或可等待对象

    将会发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-19
      • 1970-01-01
      • 1970-01-01
      • 2019-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多