workerman 5.2.3中onmessage的$data是decode()返回的业务数据而非原始字节流;需实现input/decode/encode三个静态方法,worker初始化时须显式设置protocol为完整命名空间类名,$data可直接按decode约定类型使用。

Workerman 5.2.3 中,自定义协议的 onMessage 回调不是直接接收原始字节流,而是接收经协议层解析后的“业务数据”——也就是说,onMessage 的 $data 参数已经是 decode() 方法返回的结果,不再是裸 TCP 数据包。
要正确使用它,关键在于协议类实现是否到位,以及Worker 实例是否正确绑定了该协议。下面分三块说清楚:
协议类必须实现三个静态方法
你的自定义协议类(比如 `MyProtocol`)需包含:• input(string $buffer):判断缓冲区里是否有完整包。返回 0 表示不够,返回正整数表示当前可取走的字节数(如包头4字节+包体长度字段,就靠它截出整包)。
• decode(string $buffer):对已截出的完整包做解码,返回你想要的 PHP 数据(如数组、对象、字符串)。这个返回值,就是 `onMessage` 中的 `$data`。
• encode(mixed $data):把 `send()` 时传入的数据转成二进制流发出去。`onMessage` 里不调用它,但发送逻辑依赖它。
Worker 初始化时指定协议类
不能只写 `new Worker('tcp://0.0.0.0:8888')` 就完事。必须显式传入协议类名:```php
$worker = new Worker('tcp://0.0.0.0:8888');
$worker->protocol = MyProtocol::class;
```
onMessage 回调里直接处理业务数据
此时 `$data` 是 `decode()` 的返回值,类型由你控制:• 如果 `decode()` 返回 `['type'=>'login','user_id'=>123]`,那 `$data` 就是这个数组,可直接 `if ($data['type'] === 'login') { ... }`
• 如果 `decode()` 返回 JSON 字符串,`$data` 就是字符串,需 `json_decode($data, true)`(除非你故意让它保持字符串)
• 不再需要手动 `unpack()`、`substr()` 或判断包长——这些都在 `input` 和 `decode` 里完成了
只要协议类无逻辑错误、Worker 正确绑定、onMessage 函数签名保持 function($connection, $data),整个链路就跑通了。不需要额外注册或启动协议引擎,Workerman 会在底层自动调度 input → decode → onMessage。











