
这是一种极简的、异步的、双向的 JSON-RPC 2.0 协议实现,它通过换行符分隔的 JSON 数据流进行通信。该协议基于 amphp 字节流协议,并利用了 Revolt 事件循环机制来加速处理流程。
这是一个基于 JSON-RPC 的库:它提供了一种长寿命的连接方式,双方可以通过该连接发送请求和通知,响应传入的请求,并按任意顺序处理返回的结果。这种机制是如 Language Server 协议和 Model Context 协议等 stdio 协议的基础。
区别于传统 PHP JSON-RPC 库(单向 HTTP、区分客户端/服务端、同步阻塞),它是对等 Peer 模型:单条长连接两端可互相发起调用、推送通知,响应可乱序返回,专为 stdio 进程双向通信设计,是 LSP(语言服务协议)、MCP(模型上下文协议)底层基础组件。

Cancellation 协作式取消机制。composer require fabpot/json-rpc-peer
use Amp\ByteStream;
use Fabpot\JsonRpc\JsonRpcDispatcher;
use Fabpot\JsonRpc\JsonRpcPeer;
$input = ByteStream\getStdin();
$output = ByteStream\getStdout();
$peer = new JsonRpcPeer($input, $output);
$dispatcher = new JsonRpcDispatcher($peer);
根据方法名称来注册处理程序。当请求处理程序返回结果时,调度器会将其作为 JSON-RPC 响应发送出去。
$dispatcher->onRequest('sum', function (array $params): array {
return ['total' => array_sum($params['values'])];
});
通知处理程序不返回任何内容,因为通知本身并没有对应的响应机制:
$dispatcher->onNotification('log', function (array $params): void {
fwrite(\STDERR, $params['message']."\n");
});
在注册了处理程序之后,调用 listen() 。它会读取并分发消息,直到输入流到达末尾或被关闭。之后,它会请求取消正在运行的处理程序,并等待它们完成工作后再返回。
$peer->listen();
JsonRpcPeer:底层流读写、消息收发、连接管理JsonRpcDispatcher:方法路由、请求/通知处理器注册、取消管理JsonRpcError:JSON-RPC 2.0 标准错误码常量JsonRpcException:RPC 业务异常封装PsrTrafficLogger:流量日志(自动脱敏密钥、token、密码等敏感字段)$/cancelRequest)listen() 持续监听消息
常量 | 错误码 | 场景 |
|---|---|---|
PARSE_ERROR | -32700 | JSON 格式非法 |
INVALID_REQUEST | -32600 | 消息不符合 RPC 格式 |
METHOD_NOT_FOUND | -32601 | 未注册对应方法 |
INVALID_PARAMS | -32602 | 参数校验失败 |
INTERNAL_ERROR | -32603 | 处理器异常/返回值无法序列化 |
库自动抛出前3类错误;业务参数错误手动抛 JsonRpcException;未捕获异常统一转为内部错误,不泄露原始异常信息。
Cancellation 对象,处理器可接收第二个参数使用。$cancellation->throwIfRequested() 中断任务;Amp 延迟/IO 原生支持取消。支持混合请求+通知批量发送:
BatchRequest:会返回 Future,可 await 获取结果BatchNotification:无响应,无返回值 批量响应顺序与处理完成顺序一致,不匹配发送顺序;通知不会出现在响应数组。PsrTrafficLogger 对接任意 PSR-3 日志,自动脱敏 token/password/authorization 等敏感 key,支持自定义扩展敏感字段,记录收发原始 JSON 行,用于调试协议交互。
$peer->listen():阻塞监听流,直到流 EOF/关闭;关闭前等待所有活跃协程执行完毕。Amp\async(fn() => $peer->listen()),主线程可同时向外发请求。$input->close() 或远端关闭输出,触发 listen 退出;ConnectionClosedException;request() 直接抛连接异常。维度 | fabpot/json-rpc-peer | 传统 HTTP JSON-RPC 库 |
|---|---|---|
通信模型 | 对等双向,两端可互调 | 单向,客户端请求、服务端响应 |
连接 | 持久双工流 | 单次 HTTP 请求即销毁 |
并发 | 异步协程,多请求并行 | 同步阻塞,串行处理 |
传输 | stdio/TCP/内存流,无绑定 | 仅 HTTP |
取消机制 | 原生支持任务取消 | 无内置取消 |
协议适配 | 原生支持 LSP/MCP | 不兼容进程双向协议 |