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

MacOS环境下Python WebSocket客户端运行后立即断开连接问题

WebSocket连接异常排查与解决方案

先做无代码连通性验证,排除非代码层问题

  • 打开Mac终端,直接运行以下命令模拟WebSocket握手请求:
    curl -v -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" -H "Sec-WebSocket-Version: 13" https://echo.websocket.org
  • 如果命令直接返回握手失败、TLS报错、连接被重置,说明问题完全不在Python代码层,按后续对应场景排查即可;如果命令能正常返回101 Switching Protocols的响应,再回去检查Python依赖的配置问题。

最常见根因排查(占Mac环境同类问题90%以上)

1. 修复TLS证书校验的默认路径问题

Mac环境下,无论你用的是官方Python安装包还是pyenv等工具管理的Python版本,默认不会自动读取Mac系统钥匙串的根证书库,而websocket-client库默认开启严格TLS证书校验,因为找不到合法的根证书文件,会在TLS握手阶段直接断连,不会触发on_open回调,直接走到on_close逻辑。
解决步骤:

  • 安装certifi根证书库:
    pip install certifi
  • 给WebSocket初始化配置传入正确的SSL参数,修改后的代码片段:
import ssl
import certifi
import websocket

SOCKET = "wss://echo.websocket.org"

def on_open(ws):
    print('opened connection')
    ws.send("hi")
def on_close(ws):
    print('closed connection')
def on_message(ws, message):
    print(message.upper())
    ws.close()

ws = websocket.WebSocketApp(
    SOCKET, 
    on_open=on_open,
    on_close=on_close, 
    on_message=on_message,
    sslopt={"ca_certs": certifi.where(), "cert_reqs": ssl.CERT_REQUIRED}
)
ws.run_forever()

注意:不要图方便直接把cert_reqs设为ssl.CERT_NONE跳过证书校验,会带来TLS安全风险。

2. 升级websocket-client依赖版本

Python 3.9 本身已经完整支持TLS 1.2/1.3协议,但较早版本的websocket-client(0.58.0之前的版本)默认TLS握手参数和目标服务端要求不兼容,会直接被网关断连。
解决步骤:
pip install --upgrade websocket-client
升级到当前最新稳定版即可解决适配问题。

网络层问题排查

如果前面的命令行裸测也连不上目标地址,说明是本地网络栈的问题:

  • 检查本地代理配置:Mac系统开启的全局代理不会被Python进程自动读取,websocket-client默认不会复用系统代理配置,这会导致请求直接被本地网络栈丢弃、连接超时后触发on_close。如果你的网络环境必须通过代理访问外网,给run_forever方法传入代理参数:
# 把下面的host和port换成你本地实际的代理地址和端口
ws.run_forever(http_proxy_host="127.0.0.1", http_proxy_port=7890)
  • 检查本地防火墙、终端/IDE的网络权限:Mac的防火墙会默认拦截未授权的Python进程发起的对外连接,在系统设置的防火墙规则里,把对应运行代码的Python程序添加到允许列表即可。

快速定位实际断连原因

如果以上调整后还是触发异常断连,打开websocket库的trace日志,把实际的断连原因打印出来,避免无方向排查:
在import websocket后加入一行代码:

websocket.enableTrace(True)

运行代码时会输出从TCP建连、TLS握手、HTTP升级握手的全流程日志,明确标注断连的具体原因(比如证书校验失败、版本不兼容、网关拒绝连接等)。

正常运行的判断标准

修复完成后,代码的运行输出顺序应该是:

  1. 先打印opened connection
  2. 收到服务端返回的消息后打印HI
  3. 最后执行ws.close()时打印closed connection
    如果顺序颠倒,先输出closed connection,说明握手流程完全没有走完,对照前面的步骤逐项排查即可。

内容的提问来源于stack exchange,提问作者Robee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 18:36:03