workerman 5.2.3 自定义协议类需在protocols命名空间下实现public static input、decode、encode方法;input判断包边界,decode/encode负责二进制与php数据双向转换,worker实例化时用"类名://地址:端口"启用。

Workerman 5.2.3 编写自定义协议类,核心是实现一个含 input、decode、encode 三个静态方法的 PHP 类。它不依赖接口继承,而是靠命名空间和方法签名被框架自动识别。只要类放在 Protocols 命名空间下,且方法声明正确,Workerman 就会在 TCP 连接中自动调用它们处理粘包、解包与封包。
协议类基础结构与位置要求
协议类必须满足以下硬性条件:
- 文件路径建议为
Protocols/YourProtocol.php(如项目根目录下的app/Protocols/JsonNL.php) - 命名空间必须是
Protocols(不能是App\Protocols或其他,除非你手动注册 autoload) - 类名任意,但三个方法必须全部为 public static,且参数/返回值类型与框架预期一致
- 不需要
implements任何接口,Workerman 通过反射检查方法存在性
input 方法:精准判断数据包边界
这是解决 TCP 粘包/拆包的关键。它接收原始字节流 $buffer,只做一件事:告诉 Workerman「当前缓冲区里有没有一个完整包?如果有,长度是多少?」
- 返回 正整数 → 表示发现完整包,长度即返回值,Workerman 会截取该长度交给
decode - 返回 0 → 表示数据不足,继续收包,不触发后续流程
- 返回 false 或 -1 → 主动断开当前连接(用于协议校验失败场景)
常见实现方式:
-
换行分隔:
$pos = strpos($buffer, "\n"); return $pos === false ? 0 : $pos + 1; -
固定包头+长度字段(如前4字节为 body 长度):
if (strlen($buffer) = 4 + $len ? 4 + $len : 0;
decode 与 encode:业务数据与二进制流的双向转换
decode 在 input 返回有效长度后被调用,参数是已截取的完整原始数据;encode 在调用 $connection->send($data) 时被调用,参数是 PHP 变量(如数组或字符串)。
-
decode($buffer):把二进制数据转成 PHP 可用结构。例如return json_decode(trim($buffer, "\n"), true); -
encode($data):把 PHP 数据转成网络可传输格式。例如return json_encode($data, JSON_UNESCAPED_UNICODE) . "\n"; - 二者需严格对应——
encode加的换行,decode就得去掉;encode用 big-endian 打包长度,decode就得用相同方式解析
在 Worker 中启用协议类
创建 Worker 实例时,直接把协议类名作为传输层协议传入即可,格式为 "协议类名://地址:端口":
$worker = new Worker("JsonNL://0.0.0.1:8000");
注意:不是 "Protocols\JsonNL://...",Workerman 会自动在 Protocols 命名空间下查找类。启动后,所有连接都会走你定义的 input/decode/encode 流程,$data 直接以解码后的结果传入 onMessage 回调。











