Webman是PHP框架webman(小写),非Java或C项目;需安装webman/websocket插件,显式注册Ws路由,Nginx反代必须配置proxy_http_version 1.1、Upgrade和Connection头,WebSocket连接独立于HTTP生命周期。

Webman 不是 PHP 框架,它不支持 PHP。所有声称“PHP Webman”或“Webman 集成 WebSocket”的教程,要么混淆了技术栈,要么存在根本性事实错误。
你看到的「Webman」相关资料实际指向三个完全不同的项目,必须立刻区分:
-
Webman(Java):基于 Java 的 Web 框架,使用WebmanWebSocket类和WebmanWebSocketHandler接口,运行在 JVM 上; -
Webman(C):轻量级 C 语言服务器,依赖libev和libwebsockets,无 PHP 绑定; -
webman(PHP):这是 Workerman 团队推出的 PHP 框架,正确名称是webman(全小写),不是 Webman —— 它底层基于 Workerman,原生支持 WebSocket,但官方文档和命名中从不写作 “Webman”。
所以,如果你在 PHP 项目里想用 webman(小写)做实时推送,下面才是真实可行路径。
如何用 PHP 的 webman 框架启动 WebSocket 服务
webman 是一个现代、路由驱动的 PHP 框架,其 WebSocket 支持通过插件 webman/websocket 提供,不是开箱即用。
- 必须先安装插件:
composer require webman/websocket - 插件启用后,WebSocket 路由需显式注册,例如在
config/route.php中添加:use support\Ws; </li></ul><p>return [ Ws::on('connect', [app\controller\WsController::class, 'onConnect']), Ws::on('message', [app\controller\WsController::class, 'onMessage']), Ws::on('close', [app\controller\WsController::class, 'onClose']), ];-
WsController必须实现三个方法,且不能依赖$this->app或中间件上下文——WebSocket 连接生命周期独立于 HTTP 请求,$connection是唯一可靠参数 - 启动命令仍是
php start.php start,但需确保进程以 daemon 模式运行(非start -d时可能被终端中断)
这是最常踩的坑:开发者习惯在控制器里写webman的onMessage回调里不能直接调用 Laravel/ThinkPHP 风格的 FacadeCache::get()或Db::table()->insert(),但在 WebSocket 连接上下文中:-
Cache、Db等 Facade 依赖 HTTP 请求生命周期初始化的连接池和上下文,onMessage中它们可能未就绪或复用错连接 - 所有数据库操作建议改用原生 PDO 实例(手动管理连接),或使用
webman提供的support\Db工具类(它不走 Facade,而是直连) - 日志写入要避开
Log::info()(可能阻塞协程),改用support\Log的异步写入接口,或直接file_put_contents(..., FILE_APPEND)
前端连不上
ws://?检查 Nginx 反向代理配置是否漏掉 upgrade 头webman默认监听0.0.0.0:2346(WebSocket 专用端口),生产环境必须反代。Nginx 配置中这三行缺一不可:proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";
少任意一行,浏览器控制台就会报错:
WebSocket connection to 'ws://xxx' failed: Error during WebSocket handshake: Unexpected response code: 400或502。立即学习“PHP免费学习笔记(深入)”;
另外,
webman的 WebSocket 路由默认挂载在/websocket路径下,Nginx location 应匹配该路径,而非根路径;否则握手请求无法被框架捕获。WebSocket 在
webman中不是“附加功能”,它是独立于 HTTP 的通信通道,连接管理、心跳、广播、连接数限制都得单独配置——别指望它自动继承 HTTP 中间件或 Session。 -



















