Workerman 5.2.3 不提供也不需要 read 方法;其自定义协议仅强制要求 input、decode、encode 三个静态方法,用于包长判断、解包和封包,所有 socket 接收与缓冲管理均由框架内部完成。

Workerman 5.2.3 没有 read 方法,也不需要你实现它。
你看到的 read 方法,很可能是混淆了其他框架(如 Swoole 的 onReceive 回调或底层 socket fread/stream_socket_recvfrom)——Workerman 的自定义协议接口只强制要求三个静态方法:input、decode、encode。这是从 Workerman 3.x 到 5.x 一直稳定延续的核心契约,5.2.3 版本完全沿用该设计。
如果你在文档、示例或报错中遇到 read,基本属于以下情况之一:
- 把
onMessage回调误称为“read”逻辑(实际是业务层接收处理,不是协议层) - 混淆了自定义 Worker 类里手动
recv()的原始 socket 操作(Workerman 已封装,不应直接干预) - 看到了过时教程或非官方扩展代码
✅ 正确做法:专注写好这三个方法
1. input(string $buffer): int|false
判断当前缓冲区 $buffer 是否含一个完整数据包,返回其字节长度;不够则返回 0;出错可返回 false(连接将被关闭)。
public static function input(string $buffer): int
{
// 假设协议:前4字节为包体长度(网络字节序),后续为JSON内容
if (strlen($buffer) < 4) {
return 0; // 包头都没收全
}
$len = unpack('N', $buffer)[1]; // 读取大端4字节长度
$total = 4 + $len;
return strlen($buffer) >= $total ? $total : 0;
}2. decode(string $buffer): mixed
对 input 返回长度所截取的完整 $buffer 进行解包,返回 PHP 可用数据(如数组、对象)。
public static function decode(string $buffer): array
{
$len = unpack('N', substr($buffer, 0, 4))[1];
$json = substr($buffer, 4, $len);
return json_decode($json, true) ?: [];
}3. encode(mixed $data): string
将业务层传入的 $data(比如 onMessage 里 $connection->send($data) 的 $data)序列化并打包成二进制流。
public static function encode(mixed $data): string
{
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
$len = strlen($json);
return pack('N', $len) . $json; // 4字节长度 + JSON体
}? 注意事项
- 所有方法必须是
public static - 类需放在
Protocols/目录下,命名空间为Protocols(如Protocols\MyProto) - 协议类不参与实例化,Workerman 仅通过反射调用静态方法
- 不要尝试在协议类中读 socket、调用
recv或fread—— 这会破坏 Workerman 的事件循环和缓冲管理
你真正要“读”的数据,已由 Workerman 内部完成接收、拼接和分包,你只需告诉它:
→ 多长才算一包(input)
→ 这包怎么拆成 PHP 数据(decode)
→ PHP 数据怎么打成包(encode)
不需要、也不应该写 read。

















