Skip to content

WebSocket 握手失败 ​

问题现象 ​

页面能打开,但实时连接失败;握手返回 200、301、400 或 403,没有 101 Switching Protocols。

适用环境 ​

浏览器 WebSocket、HTTPS 反向代理、具备 WebSocket 端点的服务。

本文是可复用的排障示例,不代表某次个人生产事故。命令中的名称、账号和数据均为示例,执行前请替换为已确认的目标。

复现或诊断步骤 ​

  1. 在浏览器 Network 的 WS 项检查 URL、Origin、状态和响应头,勿把带令牌 URL 复制到公开日志。
  2. 比较代理转发路径与后端端点,确认是否多加或剥离前缀。
  3. 在同一网络内测试后端,并检查认证、Origin 允许列表、Upgrade 支持和空闲超时。

原因分析 ​

HTTPS 页面连接 ws:// 会触发混合内容限制。路由前缀错误可能把握手交给普通 HTML 服务。Caddy reverse_proxy 原生支持 WebSocket;Nginx 常需显式传递 Upgrade 与 Connection。握手成功后立即关闭则应继续检查应用协议和授权。

修复示例 ​

caddyfile
app.example.com {
  @socket path /socket /socket/*
  handle @socket {
    reverse_proxy realtime:8080
  }
  handle {
    reverse_proxy web:8080
  }
}
# handle 保留原始 /socket 路径;不要无意换成 handle_path

浏览器使用 wss://,保持后端约定的路径和认证方式。配置心跳与合理空闲超时;更新代理前保存旧配置,说明热加载可能使长连接需要重连。客户端重连应退避,并重新完成授权。

验证方法 ​

确认浏览器握手 101,再验证实际消息收发、空闲后的心跳与断线重连。没有有效登录凭据时,只能验证路由与握手拒绝原因,不能宣称完整会话成功。

常见误区 ​

仅凭首页 200 不代表 WebSocket 正常。不要盲目允许所有 Origin,也不要把 WebSocket 令牌放入截图或工单;HTTP/2 扩展连接机制与 HTTP/1.1 握手需按链路区分。

官方参考链接 ​

相关分类:部署与运维 · 全部笔记