Webman需在start.php中手动创建Worker实例监听websocket://协议,不可仅靠config/server.php配置;必须启用pcntl和posix扩展,显式注册onConnect/onMessage/onClose回调,并自行管理uid连接映射与跨进程广播。

Webman 本身不内置 WebSocket 服务器,但通过 Workerman 原生能力可直接支撑高并发 IM 场景——关键不是“能不能”,而是“怎么组织连接、路由和广播逻辑才不掉消息、不崩进程”。
WebSocket 服务必须手动注册到 start.php
Webman 的 start.php 是入口,但默认只启动 HTTP 服务。要跑 WebSocket,得显式 new 一个 Worker 实例并监听 websocket:// 协议。
- 不能只改
config/server.php就生效——那个配置只影响 HTTP Worker,对 WebSocket 无效 - 必须在
start.php末尾(Worker::runAll()之前)追加 WebSocket Worker 定义 - 端口别跟 HTTP 冲突:HTTP 默认
8787,WebSocket 建议用2345或9502 - 记得调用
$worker->onMessage、onConnect、onClose,否则连接建立后收不到任何数据
用户连接管理必须自己维护 uid → connection 映射
Webman 没有 connectionManager 这类封装,所有连接生命周期都靠你存取全局数组或 Redis。不处理好,就无法私聊、踢人、状态同步。
- Workerman 的
$worker->connections是 raw connection 列表,不含业务身份,不能直接用 - 推荐在
onConnect里解析 token 或 query 参数(如?uid=123&token=abc),校验后存入$worker->uidConnections[123] = $connection - 务必在
onClose中 unset 对应 uid,否则内存泄漏 + 重复推送 - 若需跨进程广播(比如多 worker 实例),必须用 Redis pub/sub 或
Worker::$pidMap配合sendToAll,不能只依赖单进程数组
消息广播性能瓶颈常出在 JSON 编码和遍历方式
万级在线时,一次群聊广播若用 foreach 遍历所有 connection 再逐个 $conn->send(),CPU 和网络栈压力会陡增。
立即学习“PHP免费学习笔记(深入)”;
- 避免在广播循环里做
json_encode($msg)—— 提前 encode 一次,复用字符串 - 不要用
foreach ($worker->connections as $conn),改用foreach ($worker->uidConnections as $conn),跳过未登录/断连的脏连接 - 大群消息建议拆包:先发 header(含 msg_id、type、seq),再发 payload,前端按序组装,降低单次 send 负载
- 敏感操作(如撤回、已读)必须带时间戳和服务端 seq,防止客户端伪造或乱序
调试时看不到 WebSocket 连接?检查这几个硬性条件
浏览器控制台显示 WebSocket connection to 'ws://...' failed,90% 不是代码问题,而是环境卡点。
- 确保启动命令带
-d:运行php start.php start -d,否则 WebSocket Worker 不加载(默认只启 HTTP) - 检查 PHP 是否启用
pcntl和posix扩展——缺一不可,php -m | grep -E 'pcntl|posix'验证 - Nginx 反向代理 WebSocket 必须透传 Upgrade 头:
proxy_set_header Upgrade $http_upgrade;+proxy_set_header Connection "upgrade"; - 防火墙/安全组是否放行了 WebSocket 端口?本地测试用
telnet localhost 2345直连验证底层通不通
真正难的不是写通连接,而是让十万连接共存时不丢帧、不串号、不超时。每个 onMessage 回调里那几十毫秒的处理延迟,乘上并发数就是雪崩起点。别迷信“框架自动搞定”,Webman 给你的是 Workerman 的裸能力,剩下的,得一行行压测出来。



















