workerman 4.0.34 与 webman 组合是轻量可控的高性能 php 服务方案;需通过 composer require workerman/workerman:4.0.34 --with-all-dependencies 锁定版本,避免定时器异常;再在 config/server.php 中添加 websocket 服务配置以与 http 共享端口。

要在生产环境中快速启动一个支持 WebSocket 和 HTTP 的高性能 PHP 服务,Workerman 4.0.34 与 Webman 框架组合是最轻量且可控的选择——它不依赖 Swoole,纯 PHP 实现,兼容 PHP 8.1~8.3,且能直接复用 Composer 生态。
初始化 Webman 项目并锁定 Workerman 版本
执行命令创建项目:composer create-project webman/console myapp。
进入项目目录后,立即降级或锁定 Workerman 到 4.0.34:composer require workerman/workerman:4.0.34 --with-all-dependencies。这一步必须做,因为 Webman 默认拉取最新版 Workerman,而 4.0.35+ 引入了对 【Swoole 驱动的隐式 fallback 行为】,会导致纯 Workerman 模式下定时器异常触发两次。
检查 composer.lock 中 workerman/workerman 的 version 字段是否确为 4.0.34,否则后续 WebSocket 连接会偶发断连。
启用 WebSocket 服务并绑定到 HTTP 端口
Webman 默认只开 HTTP 服务。要让 WebSocket 和 HTTP 共享 8787 端口(避免跨域调试),需手动修改 config/server.php:
在 'servers' 数组中追加一个 'websocket' 服务配置项,内容如下:
[ 'name' => 'websocket', 'type' => 'websocket', 'host' => '0.0.0.0', 'port' => 8787, 'process_name' => 'webman-websocket', 'context' => [] ]。
注意:不能删掉原有的 'http' 服务项,Webman 要求 HTTP 服务必须存在才能加载路由和中间件;WebSocket 服务会自动复用同一端口的 upgrade 协议握手逻辑。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
编写 WebSocket 消息处理逻辑
在 app/controller 下新建 WsController.php,内容如下:
<?php namespace app\controller; use support\Request; use Webman\App; class WsController { public function onConnect(Request $request) { echo "Client {$request->fd} connected\n"; } public function onMessage($connection, $data) { $connection->send("echo: {$data}"); } public function onClose($connection) { echo "Client {$connection->fd} closed\n"; } }
然后在 config/bootstrap.php 末尾添加注册语句:Webman\App::on('websocket.connect', [app\controller\WsController::class, 'onConnect']); Webman\App::on('websocket.message', [app\controller\WsController::class, 'onMessage']); Webman\App::on('websocket.close', [app\controller\WsController::class, 'onClose']);。
这三行注册必须写全,缺任意一个都会导致对应生命周期事件静默丢失——【Webman 不会报错,但连接不会触发 onConnect】。
启动服务并验证 WebSocket 连通性
执行 php start.php start -d 启动守护进程。
使用浏览器控制台运行以下代码测试连接:const ws = new WebSocket('ws://127.0.0.1:8787'); ws.onopen = () => ws.send('hello'); ws.onmessage = e => console.log('recv:', e.data); 。
若控制台输出 recv: echo: hello,说明 WebSocket 通道已通;此时再查看终端日志,应同时看到 Client xxx connected 和 Client xxx closed 两行——证明握手、通信、断连全流程闭环。










