17370845950

php连接websocket返回码101啥意_php连接websocket状态码含义【说明】
HTTP状态码101表示协议升级成功,是WebSocket握手成功的正常响应,并非错误;其后连接中断多因服务端未持续运行、配置缺失或响应体污染导致。

HTTP 状态码 101 表示握手成功,不是错误

PHP 本身不直接发起 WebSocket 握手(那是浏览器或客户端如 curlReactPHPWorkerman 等做的),但当你用 PHP 搭建 WebSocket 服务端(比如基于 RatchetSwoole),或用 PHP 写反向代理配置时,看到响应返回 101 Switching Protocols

,说明 HTTP 协议升级成功——连接已从 HTTP 切换为 WebSocket,这是预期中的「成功信号」,不是报错。

常见误解是把 101 当成“请求失败”,其实它和 200 一样属于成功状态码,只是语义不同:200 是 HTTP 响应完成,101 是协议切换完成。

为什么 PHP 服务端返回 101 后连接却断了?

返回 101 只代表握手阶段通过,后续能否通信取决于服务端是否真正接管 WebSocket 数据帧。很多 PHP 实现卡在这一步:

  • Ratchet 需要运行在长期存活的守护进程里,不能走传统 PHP-FPM —— 否则握手完进程就退出,连接立刻中断
  • Swoole\WebSocket\Server 必须显式调用 $server->start() 并保持事件循环运行;若漏掉 on('open')on('message') 回调,客户端发消息会无响应,最终超时断连
  • 用 Nginx 反代时,必须透传 Upgrade 头:proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "Upgrade"; 缺一不可,否则后端收不到 Sec-WebSocket-Key,无法生成 Sec-WebSocket-Accept

浏览器控制台看到 101 但 socket.readyState 是 0?

这说明握手虽被服务器接受,但客户端没收到合法的 WebSocket 升级响应,常见原因:

  • 服务端返回的 Sec-WebSocket-Accept 值计算错误(必须对 Sec-WebSocket-Key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 做 SHA1 + Base64)
  • 响应体里混入了额外输出(比如 PHP 的 echo、BOM 字节、错误日志、var_dump),导致 WebSocket 帧解析失败
  • 用了 wss:// 但服务端没配 TLS,或证书不被浏览器信任,握手会被静默拦截(此时 Network 面板可能看不到 101,只显示 failed)

验证方式:console.log(socket.readyState) 应该从 0(CONNECTING)变为 1(OPEN);如果卡在 0 或直接跳到 03(CLOSED),基本是上述某处出问题。

PHP 客户端连接 WebSocket 时拿不到 101?

标准 PHP(ext/curlfile_get_contents)无法发起 WebSocket 握手,因为它们只支持 HTTP 协议栈,不处理 Upgrade 流程和后续二进制帧。你看到的“PHP 连接 WebSocket”实际分两类:

  • ReactPHP / Amphp / Swoole\Http\Client 等异步客户端:它们自己实现 WebSocket 握手逻辑,101 由这些库内部处理,你通常看不到原始状态码
  • cURL 手动模拟握手:能发 GET 请求并收到 101 响应头,但 cURL 无法继续收发 WebSocket 帧——它会在收到响应后立即关闭连接,所以这不是真正的 WebSocket 连接

真要用 PHP 主动连 WS/WSS,必须选支持 WebSocket 协议栈的客户端库,而不是依赖内置 HTTP 函数。

最易被忽略的一点:101 是 HTTP 层面的终点,却是 WebSocket 层面的起点。所有业务逻辑(鉴权、心跳、消息路由)都发生在 101 之后,而这一段完全脱离 HTTP 规范——PHP 开发者习惯用 request/response 思维,容易在帧解析、连接保活、并发管理上栽跟头。