websockets库强制依赖asyncio,所有核心函数必须在异步上下文中调用;Python版本须≥3.7,否则导入失败或协程异常;安装需避免混淆websocket-server;serve()三参数不可缺,connect()须用async with;recv()和send()必须await;须捕获ConnectionClosed异常以防静默失联。

websockets 库不是“装上就能跑”的同步工具,它强制依赖 asyncio,所有核心函数(如 websockets.serve()、websockets.connect())都必须在异步上下文中调用。跳过异步结构直接写同步逻辑,会立刻报 RuntimeError: no running event loop 或 TypeError: object ... can't be used in 'await' expression。
安装前必须确认 Python 版本 ≥ 3.7
低于 3.7 的环境无法导入 asyncio 的完整 API,会导致 import websockets 失败或运行时协程异常。验证方式很简单:
python -c "import sys; print(sys.version_info >= (3, 7))"
- 返回
True才继续安装;否则升级 Python 或换环境 - 推荐用
python -m venv ws_env创建干净虚拟环境,避免系统级包冲突 - 不要混用
pip install websocket-server(另一个同名但不兼容的库),它和websockets完全无关,装错会导致ModuleNotFoundError: No module named 'websockets'
websockets.serve() 启动服务器的三个硬性参数
常见错误是只传 handler 和 port,漏掉 host 或写错类型:
- 第一个参数是协程函数(如
async def handler(ws, path): ...),不能是普通函数 - 第二个参数是字符串形式的 host,
"0.0.0.0"(允许外网访问)和"localhost"(仅本机)效果不同,别写成127.0.0.1—— 虽然能连,但某些客户端会因协议头不匹配拒绝握手 - 第三个参数是整数 port,
8765是常用测试端口,但若被占用会静默失败,建议启动后立即用lsof -i :8765(macOS/Linux)或netstat -ano | findstr :8765(Windows)确认端口是否真在监听
客户端连接必须用 async with websockets.connect()
很多人照抄示例却把 async with 写成普通 with,或者在非 async 函数里直接调 websockets.connect(),结果卡死或抛出 InvalidStateError:
- 连接 URI 必须以
ws://或wss://开头,http://会直接报InvalidURI: Expected 'ws://' or 'wss://' - 如果服务端启在
"0.0.0.0",客户端 URI 应写"ws://127.0.0.1:8765"或"ws://localhost:8765",不要用"ws://0.0.0.0:8765"—— 这个地址本身不可路由 - 接收消息必须用
await websocket.recv(),不能用websocket.recv()(那是阻塞式旧接口,已移除)
调试时最容易忽略的异常捕获点
WebSocket 连接中断非常常见(网络抖动、客户端关页、超时),但默认不抛出明显错误,只让 async for message in websocket: 循环退出。不加防护会导致协程静默结束,服务端“看起来还在跑”实则已失联:
立即学习“Python免费学习笔记(深入)”;
- 务必在
async for外层包try/except websockets.exceptions.ConnectionClosed - 发送前检查连接状态:
if websocket.open: await websocket.send(...),否则可能触发ConnectionClosedOK - 日志里出现
WebSocket connection is closed: code = 1001表示客户端主动关闭;code = 1006是底层连接异常,通常要重连


















