PHP游戏网站用Workerman实现长连接的核心是绕开PHP-FPM短生命周期限制,需在onConnect中设$connection->keepConnection = true(TCP)或确保WebSocket正确握手,启用内置心跳(ping_interval/ping_not_response_limit),资源初始化放在onWorkerStart,配合定时清理僵尸连接。

PHP游戏网站用Workerman做长连接,核心是绕开PHP-FPM的短生命周期限制,让每个Worker进程常驻并独立维护客户端连接。关键不在“能不能连”,而在“连住后怎么不掉、不卡、不爆内存”。
必须在 onConnect 中启用连接保持
Workerman默认TCP连接发完数据就断开,WebSocket也一样——这不是bug,是设计。要长连接,第一行代码就得写对:
- WebSocket协议:无需额外设置,但必须确保客户端正确握手且不主动关闭
- TCP协议:必须在
$worker->onConnect里加$connection->keepConnection = true; - 漏掉这句,哪怕后面心跳再全,连接也会在响应后秒断
用内置心跳比手动写更稳
Workerman 4.0.34 对 WebSocket 内置了标准心跳机制,比自己解析 ping/pong 包更轻量、兼容性更好:
- 设置
$ws_worker->ping_interval = 25;(每25秒发一次 ping) - 设置
$ws_worker->ping_not_response_limit = 2;(连续2次没收到 pong 就断) - 客户端只要支持标准 WebSocket 协议(如浏览器、Unity WebSockets、LayaAir),无需改任何逻辑
- 避免手动心跳中忘记重置超时时间、或误判空帧导致假断连
资源初始化只能放在 onWorkerStart
游戏逻辑常需数据库、Redis、配置缓存等——这些不能在onConnect或onMessage里反复 new,否则每秒千次连接就会触发内存暴涨甚至崩溃:
- 在
onWorkerStart中创建 PDO、Redis 实例,并赋值给$worker或全局静态变量 - 每个 Worker 进程只初始化一次,所有该进程下的连接共享同一套后端连接
- 配合
try/catch + reconnect逻辑处理 Redis/MySQL 断连,而不是每次请求都新建
连接元信息与超时清理要配套
光有心跳还不够,得主动识别“活着但没消息”的僵尸连接:
- 在
onConnect中记录:$connection->login_time = time(); $connection->uid = null; - 在
onMessage中更新活跃时间,例如:$connection->last_active = time(); - 用
Worker::addTimer(55, function(){...})遍历连接,清理time() - $conn->last_active > 60的连接 - 定时器间隔(55秒)必须小于超时阈值(60秒),否则会漏杀
不复杂但容易忽略。真正卡住项目的,往往不是协议没选对,而是keepConnection没设、资源在错的地方初始化、或者心跳和清理阈值设反了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











