JSON-RPC 2.0 详解

JSON-RPC 2.0 详解

JSON-RPC 2.0 是一种轻量级、无状态的远程过程调用(RPC)协议,基于 JSON 格式传输数据,适用于客户端-服务器架构(可跨语言、跨平台)。其核心目标是简化远程调用流程,同时保持灵活性和通用性,广泛用于 API 交互、微服务通信等场景。

一、核心特性

  1. 无状态:每次请求独立,服务器不存储客户端状态;
  2. 语言无关:仅定义数据格式(JSON),不限定实现语言(Java、Python、Go、JS 等均支持);
  3. 简洁性:协议规范极简,仅定义必要的请求/响应字段;
  4. 支持同步/异步 :可通过 id 字段控制(有 id 为同步请求,无 id 为通知/异步);
  5. 错误标准化:定义统一的错误码格式,便于问题定位。

二、核心概念

1. 数据交换格式

所有通信数据均为 JSON 对象,编码采用 UTF-8(强制要求)。

  • 传输方式:支持 HTTP、TCP、WebSocket 等(HTTP 最常用,通常用 POST 方法);
  • Content-Type:HTTP 传输时需指定为 application/json-rpc(建议,部分实现兼容 application/json)。

2. 关键字段说明

字段名 类型 必选/可选 作用描述
jsonrpc 字符串 必选 协议版本,必须为 "2.0"(区分 1.0 版本)
method 字符串 请求必选 要调用的远程方法名(需符合标识符规则,不能以 rpc. 开头,为系统保留)
params 数组/对象 可选 方法参数(数组:按顺序传参;对象:按名称传参,推荐用对象提升可读性)
id 整数/字符串/Null 可选 请求唯一标识(用于匹配响应): - 有 id:客户端期望响应(同步请求); - 无 id:通知(异步,服务器不返回响应); - 不能用 Null 以外的无效 JSON 类型
result 任意类型 成功响应必选 方法调用成功的返回结果(无结果时可为 Null
error 对象 失败响应必选 方法调用失败的错误信息(格式见下文"错误处理")

三、请求类型与示例

JSON-RPC 2.0 有 3 种请求类型:单请求、批量请求、通知

1. 单请求(带 id,期望响应)

(1)参数为对象(推荐)
json 复制代码
// 客户端请求(调用 getUser 方法,传入 id=123)
{
  "jsonrpc": "2.0",
  "method": "getUser",
  "params": { "id": 123 },
  "id": "req-001"  // 字符串类型 id,也可设为整数(如 1)
}
(2)参数为数组(按顺序传参)
json 复制代码
// 客户端请求(调用 add 方法,传入 10 和 20,顺序对应方法参数列表)
{
  "jsonrpc": "2.0",
  "method": "add",
  "params": [10, 20],
  "id": 1
}

2. 通知(无 id,无需响应)

客户端发送后不期望服务器返回结果(异步调用):

json 复制代码
// 客户端通知(调用 log 方法,记录操作日志)
{
  "jsonrpc": "2.0",
  "method": "log",
  "params": { "action": "login", "user": "admin" }
  // 无 id 字段
}

3. 批量请求(数组格式,支持混合请求/通知)

客户端一次性发送多个请求,服务器按顺序返回响应(通知无响应):

json 复制代码
// 客户端批量请求
[
  // 第一个:带 id 的请求
  { "jsonrpc": "2.0", "method": "add", "params": [1,2], "id": 2 },
  // 第二个:通知(无响应)
  { "jsonrpc": "2.0", "method": "log", "params": { "msg": "batch call" } },
  // 第三个:带 id 的请求
  { "jsonrpc": "2.0", "method": "getUser", "params": { "id": 456 }, "id": 3 }
]

四、响应类型与示例

响应必须与请求的 id 一一对应(通知无响应),分为 成功响应失败响应

1. 成功响应(含 result

json 复制代码
// 对应上文 add 方法的成功响应(id 与请求一致)
{
  "jsonrpc": "2.0",
  "result": 30,  // add(10,20) 的结果
  "id": 1
}

2. 失败响应(含 error

error 对象必须包含 3 个字段:code(错误码)、message(错误描述)、data(可选附加信息)。

标准错误码(协议定义,不可自定义)
错误码 含义描述
-32700 解析错误:请求 JSON 格式无效
-32600 无效请求:JSON 格式有效,但不符合 RPC 规范(如缺少 jsonrpc: "2.0"
-32601 方法未找到:请求的 method 不存在
-32602 参数错误:params 格式错误或参数不匹配
-32603 内部错误:服务器执行方法时发生未知错误
-32000~-32099 服务器自定义错误:需在文档中说明具体含义
失败响应示例
json 复制代码
// 对应上文 getUser 方法的失败响应(用户不存在)
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32602,  // 参数错误(或自定义码 -32001 表示"用户不存在")
    "message": "User not found",
    "data": { "userId": 123 }  // 附加信息(可选)
  },
  "id": "req-001"  // 与请求 id 一致
}

3. 批量响应

对应批量请求,返回数组格式的响应(通知无响应,不包含在结果中):

json 复制代码
// 对应上文批量请求的响应(仅返回带 id 的请求结果)
[
  { "jsonrpc": "2.0", "result": 3, "id": 2 },  // add(1,2) 的结果
  { "jsonrpc": "2.0", "result": { "id": 456, "name": "user2" }, "id": 3 }  // getUser 的结果
]

五、关键约束与注意事项

  1. 版本强制jsonrpc 字段必须为字符串 "2.0",大小写敏感;
  2. id 匹配规则
    • 请求的 id 若为非 Null 有效值,响应必须返回相同 id
    • 若请求 id 无效(如 True、空对象),服务器返回 id: Null 的错误响应;
  3. 参数格式params 只能是数组或对象,不能是字符串、数字等原始类型;
  4. 方法名约束method 不能以 rpc. 开头(系统保留前缀);
  5. HTTP 传输建议
    • 仅支持 POST 方法(GET 方法不适合携带复杂 params);
    • 响应状态码:成功用 200 OK,解析错误用 400 Bad Request,服务器错误用 500 Internal Server Error;
  6. 批量请求限制 :若批量请求为空数组([]),服务器返回 -32600 无效请求错误。

六、跨语言实现示例

1. Python 服务端(使用 jsonrpcserver 库)

bash 复制代码
pip install jsonrpcserver
python 复制代码
from jsonrpcserver import method, serve

# 定义远程方法
@method
def add(a: int, b: int) -> int:
    return a + b

@method
def getUser(id: int) -> dict:
    if id == 123:
        return {"id": 123, "name": "Alice"}
    raise Exception("User not found")  # 抛出异常会转为错误响应

# 启动服务(默认端口 5000)
if __name__ == "__main__":
    serve()

2. Python 客户端(使用 jsonrpcclient 库)

bash 复制代码
pip install jsonrpcclient
python 复制代码
from jsonrpcclient import request, parse_response

# 发送请求
response = request("http://localhost:5000", "add", a=10, b=20)
result = parse_response(response)
print(result)  # 输出:30

# 发送带参数的 getUser 请求
response = request("http://localhost:5000", "getUser", id=123)
result = parse_response(response)
print(result)  # 输出:{'id': 123, 'name': 'Alice'}

3. JavaScript 客户端(浏览器/Node.js)

javascript 复制代码
// 浏览器端示例(使用 fetch)
async function callRpc(method, params) {
  const response = await fetch("http://localhost:5000", {
    method: "POST",
    headers: { "Content-Type": "application/json-rpc" },
    body: JSON.stringify({
      jsonrpc: "2.0",
      method,
      params,
      id: Date.now().toString()  // 用时间戳作为唯一 id
    })
  });
  const data = await response.json();
  if (data.error) throw new Error(`${data.error.code}: ${data.error.message}`);
  return data.result;
}

// 调用 add 方法
callRpc("add", { a: 10, b: 20 }).then(console.log);  // 输出 30

七、适用场景与对比

适用场景

  • 轻量级 API 交互(如前后端通信、微服务间调用);
  • 跨语言/跨平台通信(JSON 通用性强);
  • 对协议复杂度敏感的场景(相比 gRPC 更简单,无需 proto 定义)。

与其他 RPC 协议对比

协议 优点 缺点
JSON-RPC 2.0 简单、无依赖、跨语言友好、易调试 无类型校验、不支持流式传输、性能一般
gRPC 强类型、高性能、支持流式/双向通信 依赖 proto 文件、学习成本高、调试复杂
XML-RPC 成熟、跨语言支持广 XML 冗余、解析效率低

总结

JSON-RPC 2.0 是"极简实用"的 RPC 协议,核心价值在于简单性和通用性 。无需复杂的配置或定义,仅通过 JSON 格式的请求/响应即可实现远程调用,适合对性能要求不极致、追求开发效率的场景。使用时需严格遵守字段规范(尤其是 jsonrpc: "2.0"id 匹配),同时合理利用错误码和批量请求提升开发效率。

官方规范文档:JSON-RPC 2.0 Specification

相关推荐
一只爱学习的小鱼儿1 小时前
QT中3D的使用
开发语言·数据库·qt
FL16238631293 小时前
Qt自定义控件之仪表盘和水波纹圆形进度条的完整实现
开发语言·qt
开始了码5 小时前
QT::对话框:字体对话框3
qt
rainbow_lucky01068 小时前
Word-like编辑器
qt·编辑器·word-like
开始了码9 小时前
QT::对话框:颜色对话框2
qt
穆雄雄9 小时前
Qt-for-鸿蒙PC Slider 组件开源鸿蒙开发实践
qt·开源·harmonyos
还算善良_10 小时前
【XML生成】根据JSON格式化的报文,动态生成XML
xml·json
国服第二切图仔19 小时前
Qt-for-鸿蒙PC-多线程绘制开源鸿蒙开发实践
qt·开源·鸿蒙pc
国服第二切图仔21 小时前
Qt-for-鸿蒙PC-CheckBox开源鸿蒙开发实践
qt·开源·鸿蒙pc