在 workerman 5.2.3 中切换为自定义协议需指定协议 uri(如 jsonnl://0.0.0.0:8000),并实现 protocols 命名空间下的类,含 input、decode、encode 静态方法,确保自动加载。

1. 编写自定义协议类
创建一个 PHP 类,例如 app/Protocols/JsonNL.php(路径可自定义,但需保证能被自动加载):
该类必须:
• 使用 namespace Protocols;(Workerman 默认查找此命名空间)
• 包含三个 public static 方法:input、decode、encode
示例(以换行分隔的 JSON 协议):
namespace Protocols;
class JsonNL {
public static function input($buffer) {
$pos = strpos($buffer, "
");
return $pos === false ? 0 : $pos + 1;
}
public static function decode($buffer) {
return json_decode(trim($buffer), true);
}
public static function encode($data) {
return json_encode($data) . "
";
}
}
2. 在 Worker 初始化时使用协议名
不再用 "tcp://0.0.0.0:8000",而是改用:
"JsonNL://0.0.0.0:8000" —— 注意协议名(JsonNL)与类名一致,且首字母大写。
Workerman 会自动在 Protocols 命名空间下查找该类。
代码示例:
use WorkermanWorker;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('JsonNL://0.0.0.0:8000'); // ← 关键切换点
$worker->onMessage = function($connection, $data) {
// $data 已是 decode 后的数组,不是原始字符串
var_dump($data);
$connection->send(['status' => 'ok']); // 自动经 encode 处理
};
Worker::runAll();
3. 确保类可被正确加载
有三种可靠方式(任选其一):
- 将协议类放在
Protocols/目录下,并确认项目已启用 PSR-4 自动加载(Composer 默认支持"Protocols\" : "app/Protocols/") - 手动添加命名空间别名(适用于类不在
Protocols下):class_alias('app\Protocols\JsonNL', 'Protocols\JsonNL'); - 若使用 ThinkPHP + think-worker,按规范放在
app/library/,再在启动前加别名:class_alias('app\library\JsonNL', 'Protocols\JsonNL');
4. 验证是否生效
启动后,发送测试数据(如 {"cmd":"ping"}
)观察:
• 若 onMessage 中 $data 是数组而非字符串 → decode 生效
• 若客户端收到带
的 JSON 字符串 → encode 生效
• 若连续发两条不带换行的数据被合并等待 → input 正确处理粘包











