FrankenPHP 通过 Worker 模式实现 WebSocket,需手动处理 HTTP 升级、握手及消息收发;新手应先用最小脚本验证握手,避免误用 cURL 测试或依赖自动连接管理。

FrankenPHP 原生支持 WebSocket 开发,但方式和传统 PHP 框架不同——它不提供开箱即用的 WebSocket 服务器类,而是通过 Worker 模式 + 底层 PHP 脚本控制连接生命周期 实现高性能、低延迟的实时通信。对新手来说,关键不是“能不能连上”,而是理解它如何把 PHP 变成常驻进程来处理长连接。
FrankenPHP 的 WebSocket 本质是 Worker 驱动的 HTTP 升级服务
它不封装 WebSocket 协议细节(如帧解析、掩码处理),而是让开发者在 PHP 脚本中直接读取原始请求流、响应握手、收发消息。这意味着:
- 你得自己处理
Upgrade: websocket请求头和Sec-WebSocket-Accept计算(FrankenPHP 提供frankenphp_handle_request()回调入口) - 客户端仍用标准
new WebSocket("ws://...")连接,浏览器完全兼容 - 所有连接保活、心跳、广播逻辑由你的 PHP 代码控制,无隐藏中间层
新手三步快速验证 WebSocket 是否跑通
不用写完整聊天室,先确认基础链路可用:
-
第一步:准备一个最小 worker 脚本(比如
public/ws.php)
内容只需响应一次握手并返回固定消息,例如:<?php<br>if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_SERVER['HTTP_UPGRADE']) && strtolower($_SERVER['HTTP_UPGRADE']) === 'websocket') {<br> header('HTTP/1.1 101 Switching Protocols');<br> header('Upgrade: websocket');<br> header('Connection: Upgrade');<br> $key = $_SERVER['HTTP_SEC_WEBSOCKET_KEY'];<br> $accept = base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));<br> header("Sec-WebSocket-Accept: $accept");<br> echo "Handshake OK";<br> exit;<br>}<br>echo "Not a WebSocket upgrade request"; -
第二步:用 Docker 启动 FrankenPHP 并挂载该脚本
docker run -p 8080:80 -v $(pwd):/app dunglas/frankenphp php-server --worker ./public/ws.php -
第三步:浏览器控制台测试连接
const ws = new WebSocket('ws://localhost:8080');<br>ws.onopen = () => console.log('Connected');<br>ws.onerror = e => console.error(e);
如果看到Connected,说明握手成功;若报错 400 或 pending,则检查 URL 路径是否匹配、header 是否遗漏
进阶前必须避开的两个新手坑
刚上手容易卡在这两处,不是代码问题,而是模型理解偏差:
立即学习“PHP免费学习笔记(深入)”;
- 别试图用 cURL 或 file_get_contents 测试 WebSocket——它们只走 HTTP,无法维持升级后的双工通道,必然失败
- 不要期待 FrankenPHP 自动管理连接池或广播列表——它给你的是“裸金属”控制权,用户连接状态、消息路由、断连清理全靠你自己用数组、Redis 或协程变量维护
推荐下一步:用现成示例起步,再逐步替换逻辑
FrankenPHP 官方仓库里有 chat.php 示例(见 trending/frankenphp),它已实现基础消息广播和连接管理。新手可:
- 直接复制该文件到
public/下 - 用相同 Docker 命令启动:
--worker ./public/chat.php - 打开两个浏览器标签页,访问
http://localhost:8080(页面需含前端 WebSocket 连接代码) - 发送消息观察是否实时回显——通了就证明环境和协议流程都没问题
之后再按需修改 handleMessage() 里的业务逻辑,比如接入数据库存消息、加 JWT 鉴权、对接 Mercure 推送等。



















