在 Workerman 5.2.3 中注册自定义通信协议需实现 ProtocolInterface 接口,提供 input、decode、encode 三个静态方法,并通过 Worker 的 protocol 属性传入类名字符串,Workerman 启动时自动加载调用。

不需要手动注册或全局声明,Workerman 在启动时会自动根据 `protocol` 配置加载并调用你实现的三个关键静态方法:`input`、`decode`、`encode`。整个过程轻量、无侵入,完全基于约定而非配置中心或服务发现。
协议类必须实现的三个静态方法
你的自定义协议类(例如 AppProtocolsMyBinaryProtocol)需包含以下静态方法:
- input(string $buffer): int|false 判断缓冲区数据是否构成完整包。返回 0 表示数据不足,需继续等待;返回正整数表示当前可解析的包长度;返回 false 会立即关闭连接。
- decode(string $buffer): mixed 对已截取的完整数据包进行解包,返回应用层可用的数据(如数组、对象等)。若解析失败,建议抛出异常或返回 null,由 onMessage 统一处理。
- encode(mixed $data): string 将 PHP 变量(如 ['type'=>'ping','seq'=>1])序列化为二进制流(如 pack('N', 12) . json_encode(...)),确保客户端能按相同规则还原。
在 Worker 中启用该协议
创建 Worker 实例时,直接通过 protocol 属性传入协议类的完整命名空间字符串:
use WorkermanWorker;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('tcp://0.0.0.0:7777');
$worker->protocol = 'App\Protocols\MyBinaryProtocol'; // 注意双反斜杠转义
$worker->onMessage = function($connection, $data) {
// $data 已是 decode 后的结果,直接使用
var_dump($data);
$connection->send(['status' => 'ok', 'received' => $data]);
};
Worker::runAll();
协议类的典型结构示例
以“4字节包头+JSON体”为例,协议类可这样组织:
namespace AppProtocols;
class MyBinaryProtocol
{
public static function input(string $buffer): int
{
if (strlen($buffer) < 4) return 0;
$len = unpack('N', $buffer)[1];
if (strlen($buffer) < 4 + $len) return 0;
return 4 + $len;
}
public static function decode(string $buffer): array
{
$body = substr($buffer, 4);
return json_decode($body, true) ?: [];
}
public static function encode(array $data): string
{
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
$len = strlen($json);
return pack('N', $len) . $json;
}
}
注意事项与常见问题
- 类文件需能被自动加载(推荐 Composer PSR-4 规范);
- 所有方法必须为 static,且参数/返回值类型严格匹配接口要求;
- 不要在 encode/decode 中做耗时操作(如 DB 查询、远程请求),否则阻塞事件循环;
- 如果协议用于 WebSocket 场景,请注意:Workerman 的
websocket://协议底层已封装帧处理,自定义协议仅适用于tcp://或udp://; - 调试时可在
input中打印strlen($buffer)和bin2hex($buffer)辅助分析粘包/拆包行为。

















