You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python异步WebSocket服务器处理客户端异常断连时出现[WinError 121]信号量超时错误的解决方案咨询

Python异步WebSocket服务器处理客户端异常断连时出现[WinError 121]信号量超时错误的解决方案咨询

大家好,我最近在用Python的websockets库搭建异步WebSocket服务器时碰到了个棘手的问题,想请各位帮忙出出主意。

先说说具体场景:我用的是官方提供的asyncio版服务器示例代码,但当客户端异常断开连接时(比如连接着的时候突然关掉WiFi或者拔掉网线),服务器就会抛出[WinError 121]信号量超时的错误。有意思的是,我试了官方的线程版示例,完全不会出现这个报错,所以我猜测问题应该和asyncio的实现机制有关。

问题复现步骤

  • 把下面的服务器代码复制到py文件中运行
  • 准备一个WebSocket客户端工具(我用的是另一台电脑上的Postman,也可以用手机端的WebSocket客户端APP)
  • 确保服务器和客户端处于同一个局域网内
  • 确定服务器的IP地址
  • 让客户端连接到服务器
  • 在保持连接的状态下,关闭客户端的网络(比如关掉WiFi、拔网线)
  • 等待约30秒,就能看到[WinError 121]的报错信息

服务器代码

#!/usr/bin/env python

"""Echo server using the asyncio API."""

import asyncio
from websockets.asyncio.server import serve


async def echo(websocket):
    async for message in websocket:
        await websocket.send(message)


async def main():
    async with serve(echo, "0.0.0.0", 8765) as server:
        await server.serve_forever()


if __name__ == "__main__":
    asyncio.run(main())

完整报错栈

connection handler failed
Traceback (most recent call last):
  File "C:\Users\Jusuf Rrustaj\AppData\Local\Programs\Python\Python312\Lib\asyncio\proactor_events.py", 
line 286, in _loop_reading
    length = fut.result()
             ^^^^^^^^^^^^
  File "C:\Users\Jusuf Rrustaj\AppData\Local\Programs\Python\Python312\Lib\asyncio\windows_events.py", line 803, in _poll
    value = callback(transferred, key, ov)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Jusuf Rrustaj\AppData\Local\Programs\Python\Python312\Lib\asyncio\windows_events.py", line 462, in finish_socket_func
    return ov.getresult()
           ^^^^^^^^^^^^^^
OSError: [WinError 121] The semaphore timeout period has expired

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Jusuf Rrustaj\AppData\Local\Programs\Python\Python312\Lib\site-packages\websockets\asyncio\server.py", line 374, in conn_handler
    await self.handler(connection)
  File "e:\Programming\asyncio websocket\server.py", line 10, in echo
    async for message in websocket:
  File "C:\Users\Jusuf Rrustaj\AppData\Local\Programs\Python\Python312\Lib\site-packages\websockets\asyncio\connection.py", line 224, in __aiter__
    yield await self.recv()
          ^^^^^^^^^^^^^^^^^
  File "C:\Users\Jusuf Rrustaj\AppData\Local\Programs\Python\Python312\Lib\site-packages\websockets\asyncio\connection.py", line 279, in recv
    raise self.protocol.close_exc from self.recv_exc
websockets.exceptions.ConnectionClosedError: no close frame received or sent

我期望的解决方案

我希望能修改现有代码,让服务器可以识别到客户端已经异常断开连接,并且不会抛出这类错误,而是能优雅地处理这种断连情况。

备注:内容来源于stack exchange,提问作者Jusuf Rrustaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 15:58:08