Python websockets 在“发送”上静默失败

Posted

技术标签:

【中文标题】Python websockets 在“发送”上静默失败【英文标题】:Python websockets fails silently on `send` 【发布时间】:2021-02-11 13:18:01 【问题描述】:

在客户端生产者/消费者和服务器的最小 sn-p 波纹管中,我强制客户端的 send 方法出错:

import asyncio
import websockets


async def producer(websocket):
    for i in range(11):
        await websocket.send(i)  # Invalid type, fails silently
        # await websocket.send(str(i))  # Works


async def consumer(websocket):
    async for msg in websocket:
        i = int(msg)
        print(i)
        if i == 10:
            return


async def echo(websocket, path):
    try:
        async for msg in websocket:
            await websocket.send(msg)
    except websockets.exceptions.ConnectionClosedOK:
        print("Client disconnect.")


async def client():
    async with websockets.connect("ws://localhost:8765") as websocket:
        consumer_task = consumer(websocket)
        producer_task = producer(websocket)
        await asyncio.wait([consumer_task, producer_task])


loop = asyncio.get_event_loop()
loop.run_until_complete(websockets.serve(echo, "localhost", 8765))
loop.run_until_complete(client())

在无效类型的情况下,代码会无限期挂起,看起来就像它“默默地失败了”。 send 方法不应该因为无效的int 类型而引发异常吗(因为它只接受bytesstr)?

【问题讨论】:

我对 Python 中的asyncawait 不太熟悉,但我猜await asyncio.wait([consumer_task, producer_task]) 将首先等待consumer_task 完成,然后再传播引发的任何异常异步来自producer_task 如果我正在查看正确的代码here,那么在传递错误类型的data 时会引发异常 确实,我将return_when=asyncio.FIRST_EXCEPTION 作为asyncio.wait 的参数,至少现在代码不会无限期挂起。我现在正试图弄清楚如何从未来重新引发异常(尽管我猜它应该在默认情况下重新引发)。 【参考方案1】:

问题实际上在于 asyncio.wait 方法,正如 Thomas 的 cmets 所暗示的(谢谢)。切换asyncio.wait 为higher-level asyncio.gather 解决了它。

【讨论】:

以上是关于Python websockets 在“发送”上静默失败的主要内容,如果未能解决你的问题,请参考以下文章

Python websockets 在“发送”上静默失败

在 Python FastAPI 中使用 websocket 并行发送/接收

Python Quart websocket,在两个客户端之间发送数据

Python WebSocket客户端连接但不发送消息

在回调之外按需发送 websocket 消息?

Python websocket 客户端 - 从 python 代码向 WebSocketServer 发送消息