Workerman捕获客户端数据的关键是明确协议类型、确认连接真实建立、再按规则取值:TCP收裸字节流,HTTP需用$request->rawBody()或post(),WebSocket需手动json_decode,且须先验证端口监听、进程运行及网络连通性。

Workerman 5.2.3 捕获客户端数据,关键不是“能不能收到”,而是**明确协议类型、确认连接真实建立、再按规则取值**。很多问题其实卡在协议误判或网络层未通,而不是代码写错。
先确认你用的是哪种协议
Workerman 不是万能接收器,它按协议解析数据的方式完全不同:
-
TCP 协议(new Worker('tcp://0.0.0.0:2345')):客户端发什么,
$data就是什么原始字节流。没有$_POST,没有自动解析,onMessage的第二个参数就是裸数据。例如客户端用echo "hello" | nc ip 2345,$data就是字符串"hello\n"。 -
HTTP 协议(new HttpServer('0.0.0.0', 2346)):
$request是Workerman\Protocols\Http\Request对象。$_POST在 Workerman 中永远为空;必须用$request->post()(适用于表单提交)或$request->rawBody()(适用于 JSON、text/plain 等)来取体内容。 -
WebSocket 协议(new WebsocketWorker('websocket://0.0.0.0:2347')):
$data是客户端调用ws.send()发送的内容,已解包为 PHP 可读格式(字符串或二进制)。如果是 JSON 字符串,需手动json_decode($data, true)。
确保连接真通、数据真到了服务端
别急着查 onMessage 有没有触发——先验证底层是否收得到包:
- 运行
ss -tuln | grep :你的端口,确认显示的是*:2345或0.0.0.0:2345,不是127.0.0.1:2345(后者外部连不上); - 执行
ps aux | grep WorkerMan,确保 master 进程和至少一个 worker 进程都在运行; - 从客户端机器(不是 Workerman 本机)执行
telnet 服务器IP 端口,能连上才说明网络路径畅通;连不上就立刻检查安全组、防火墙、Docker 绑定地址。
在 onMessage 里正确取值的实操建议
不同协议下,最稳妥的数据捕获写法:
- TCP:
var_dump($data);直接看原始内容,注意可能含换行符、编码问题; - HTTP:
file_put_contents('/tmp/debug.log', $request->rawBody() . "\n", FILE_APPEND);先落盘看原始体,再决定用post()还是rawBody(); - WebSocket:加一句
if (is_string($data)) { $data = trim($data); },避免前端多发空格或换行干扰 JSON 解析。
常见陷阱提醒
这些地方最容易白忙活几小时:
- 网关或设备发 JSON,但 Content-Type 写成
Application/Json(首字母大写),导致 Workerman 无法识别,$request->post()返回空——务必用$request->header['content-type']打印确认; - 改了监听地址或协议后只 reload,没 stop 再 start,旧配置还驻留在内存里;
- 在
onMessage里做耗时操作(如直连 MySQL 写库),导致连接阻塞,后续数据收不到或超时重发。

















