101不是错误,是WebSocket握手成功的唯一合法响应码;它表示HTTP协议升级成功,后续通信将使用WebSocket帧格式,但返回101后连接立刻断开,通常因PHP-FPM进程退出、服务端未注册open/message回调、响应体污染、Nginx漏配Upgrade头或Sec-WebSocket-Accept计算错误所致。

101不是错误,是WebSocket握手成功的唯一合法响应码。 它只出现在HTTP升级阶段,表示服务器已确认切换协议,后续通信将脱离HTTP、走WebSocket帧格式。一旦看到101,说明网络层和TLS(如果用wss)已通,问题一定出在握手逻辑或服务端接管环节。
为什么返回101后连接立刻断开
101仅代表HTTP响应发送成功,不保证WebSocket连接真正就绪。常见断连原因包括:
- PHP-FPM等短生命周期进程处理了握手请求,但返回101后进程退出,无法维持长连接
- 服务端未注册
on('open')或on('message')回调(如Swoole/Ratchet),导致客户端发消息无响应,超时关闭 - 响应体被污染:PHP中
echo、BOM头、var_dump、错误日志输出混入HTTP响应体,破坏WebSocket帧解析 - Nginx反代漏配关键头:
proxy_set_header Upgrade $http_upgrade和proxy_set_header Connection "Upgrade"缺一不可
Sec-WebSocket-Accept值必须严格计算
浏览器会校验该字段,错误则直接关闭连接(控制台可能只显示readyState卡在0)。计算规则固定:
对客户端传来的Sec-WebSocket-Key拼接魔数"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",做SHA1哈希,再Base64编码。任何偏差(比如多空格、错字符、用MD5代替SHA1)都会导致验证失败。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
示例(Python):base64.b64encode(hashlib.sha1((key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").encode()).digest()).decode()
wss环境下101不出现的真正原因
证书问题本身不会让服务器返回非101状态码,但会导致TLS握手失败,连接在101之前就被切断。此时Network面板里根本看不到101响应,只会显示net::ERR_SSL_PROTOCOL_ERROR或直接failed。排查顺序应是:
- 先用
openssl s_client -connect host:443确认TLS是否通 - 再检查Nginx是否配置
ssl_certificate和ssl_certificate_key - 最后看浏览器地址栏是否有锁图标,点击是否提示证书无效
只要TLS不通,WebSocket握手根本不会开始,也就谈不上101。

















