Workerman 5.2.3 自定义协议需实现 ProtocolInterface 的 input、decode、encode 三个静态方法:input 判断包是否收全并返回长度,decode 将字节流转为 PHP 数据,encode 将业务数据封包;类须置于 Protocols/ 目录,命名空间 Protocols,初始化时通过 $worker->protocol 指定。

input:判断数据包是否收全
这是协议解析的第一步,决定 Workerman 是否继续等待更多数据,还是可以截取一个完整包交给后续处理。
它接收当前连接缓冲区中的原始字节流($buffer),返回值含义如下:
-
正整数:表示已识别出一个完整包,长度为该值(单位:字节),Workerman 将从缓冲区头部截取对应长度传给
decode; - 0:表示数据还不完整,继续缓存等待下一批数据;
- false 或 -1:协议异常,立即断开该客户端连接。
常见实现方式有三种:
-
换行符分隔:如
strpos($buffer, "\n") !== false ? $pos + 1 : 0; - 固定长度:直接返回预设长度(适合心跳包等);
-
包头+包体(推荐):先检查是否有足够字节读取包头(如前4字节为 body 长度),再用 unpack 解析,返回
4 + $bodyLength。
decode:把原始字节转成业务可用数据
当 input 返回非零长度且缓冲区数据足够时,Workerman 自动调用此方法,参数是刚刚截取出的完整原始包(含分隔符或包头)。
它的任务是清洗、还原、转换,最终返回 PHP 可直接操作的数据结构(如数组、对象)。
- 若协议是 JSON+换行,可做:
return json_decode(trim($buffer), true); - 若协议是二进制包头+JSON body,需先剥离包头,再对剩余部分 json_decode;
- 若含校验(如 CRC32、MD5),应在 decode 中验证,失败可 throw 异常或返回 null(建议配合 input 返回 false 断连)。
encode:把业务数据转成网络可发格式
当你在 onMessage 中调用 $connection->send($data) 时,Workerman 会将 $data 传入此方法,要求你把它“打包”成符合协议规范的二进制流。
- 对应 JSON+换行协议:
return json_encode($data) . "\n"; - 对应包头+包体协议:
$body = json_encode($data); $len = pack('N', strlen($body)); return $len . $body; - 注意:encode 的输出必须与 input 的识别逻辑严格匹配,否则收发无法对齐。
协议类注册与使用
类文件需放在项目 Protocols/ 目录下(如 app/Protocols/MyProto.php),命名空间为 Protocols,类名首字母大写。
在 Worker 初始化时指定协议:
$worker = new Worker('tcp://0.0.0.0:8000');
$worker->protocol = Protocols\MyProto::class;
无需手动调用任何方法 —— Workerman 会在收发关键节点自动触发对应静态方法。

















