JSON-RPC
一、JSON-RPC 概述
JSON-RPC 是一种基于 JSON 的轻量级 RPC(Remote Procedure Call)协议规范。它定义了客户端与服务器之间的请求-响应模式,通过 HTTP、WebSocket 等传输协议进行通信。
核心特点
- 简洁轻量:基于 JSON 格式,易于解析和生成
- 标准统一:遵循 JSON-RPC 2.0 规范,具有良好的互操作性
- 无状态:每个请求都是独立的,服务器无需维护客户端状态
- 灵活传输:可运行在 HTTP、WebSocket、TCP 等多种传输层之上
二、协议规范深度剖析
2.1 请求对象结构
1
2
3
4
5
6
{
"jsonrpc": "2.0",
"method": "add",
"params": [1, 2],
"id": 1
}
关键字段解析:
| 字段 | 类型 | 说明 | 必需 |
|---|---|---|---|
| jsonrpc | String | 协议版本,固定为”2.0” | 是 |
| method | String | 要调用的方法名称 | 是 |
| params | Array/Object | 传递给方法的参数 | 否 |
| id | String/Number/NULL | 请求的唯一标识,用于关联响应 | 否* |
*注:如果 id 为 null 或不提供,则表示通知(notification),服务器不返回响应
2.2 响应对象结构
成功响应
1
2
3
4
5
{
"jsonrpc": "2.0",
"result": 3,
"id": 1
}
错误响应
1
2
3
4
5
6
7
8
9
{
"jsonrpc": "2.0",
"error": {
"code": -32600,
"message": "Invalid Request",
"data": "Additional error information"
},
"id": 1
}
2.3 错误处理机制
标准错误码规范:
| 错误码 | 含义 | 说明 |
|---|---|---|
| -32700 | Parse error | JSON 解析错误 |
| -32600 | Invalid Request | 请求对象格式不合法 |
| -32601 | Method not found | 方法不存在 |
| -32602 | Invalid params | 参数不合法 |
| -32603 | Internal error | 服务器内部错误 |
| -32000 to -32099 | Server error | 服务器自定义错误范围 |
三、核心实现原理
3.1 请求处理流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
客户端
↓
1. 组装请求对象(method, params, id)
↓
2. 序列化为 JSON 字符串
↓
3. 通过传输层发送(HTTP/WebSocket/TCP)
↓
服务器
↓
1. 接收原始数据
↓
2. 反序列化 JSON 字符串为对象
↓
3. 验证请求格式(jsonrpc, method 必填)
↓
4. 查找并调用对应的方法
↓
5. 获取方法返回值或异常
↓
6. 组装响应对象(result/error, id)
↓
7. 序列化响应为 JSON
↓
8. 返回给客户端
3.2 参数传递机制
位置参数(Array 方式)
1
2
3
4
5
6
{
"jsonrpc": "2.0",
"method": "subtract",
"params": [42, 23],
"id": 3
}
方法签名:subtract(a, b) → 返回 19
命名参数(Object 方式)
1
2
3
4
5
6
{
"jsonrpc": "2.0",
"method": "subtract",
"params": {"subtrahend": 23, "minuend": 42},
"id": 3
}
方法签名:subtract(minuend, subtrahend) → 返回 19
3.3 批量请求处理
JSON-RPC 2.0 支持批量发送多个请求,服务器按顺序处理并返回对应的响应数组:
1
2
3
4
5
[
{"jsonrpc": "2.0", "method": "add", "params": [1,2], "id": 1},
{"jsonrpc": "2.0", "method": "subtract", "params": [5,3], "id": 2},
{"jsonrpc": "2.0", "method": "notify", "params": ["hello"]}
]
响应:
1
2
3
4
[
{"jsonrpc": "2.0", "result": 3, "id": 1},
{"jsonrpc": "2.0", "result": 2, "id": 2}
]
关键特性:
- 通知请求(无 id)不返回响应
- 响应顺序与请求顺序一一对应
- 某个请求失败不影响其他请求处理
四、关键实现细节
4.1 请求分类
1
2
3
4
5
6
┌─ JSON-RPC 请求
├─ 方法调用(有 id)
│ ├─ 成功 → 返回 result
│ └─ 失败 → 返回 error
└─ 通知(无 id 或 id=null)
└─ 服务器不返回响应
4.2 方法发现与动态调用
实现 JSON-RPC 服务器的核心在于方法注册与反射调用:
1
2
3
4
5
6
7
8
9
10
11
// 伪代码示例
type Handler map[string]func(...interface{}) interface{}
func (h Handler) Call(method string, params interface{}) (result, error) {
fn, ok := h[method]
if !ok {
return nil, MethodNotFoundError
}
// 通过反射将 params 转换为函数参数并调用
return fn(params), nil
}
4.3 异常处理三层体系
1
2
3
4
5
6
7
8
1. 协议层异常 → Parse error / Invalid Request
↓ 直接返回 error 响应
2. 方法查找异常 → Method not found
↓ 返回带 id 的 error 响应
3. 业务逻辑异常 → 方法执行错误
↓ 捕获异常,返回 Server error 响应
五、传输层实现
5.1 HTTP 传输方式
请求特征:
- 方法:POST
- Content-Type: application/json
- 请求体:JSON-RPC 请求对象
1
2
3
4
5
POST /rpc HTTP/1.1
Host: example.com
Content-Type: application/json
{"jsonrpc": "2.0", "method": "add", "params": [1,2], "id": 1}
响应特征:
- 状态码:200 OK(HTTP 层)
- 响应体:JSON-RPC 响应对象
5.2 WebSocket 传输方式
优势:
- 双向通信,支持服务器主动推送
- 连接复用,减少连接建立开销
- 更低的延迟
实现特点:
- 建立持久连接后,可双向发送 JSON-RPC 消息
- 支持异步处理多个并发请求
- 需要处理心跳(ping/pong)保活
六、与其他 RPC 协议对比
| 特性 | JSON-RPC | gRPC | Thrift | REST |
|---|---|---|---|---|
| 基础格式 | JSON | Protocol Buffers | 二进制 | JSON/XML |
| 数据体积 | 较大 | 最小 | 最小 | 较大 |
| 性能 | 中等 | 高 | 高 | 低 |
| 学习曲线 | 低 | 中 | 中 | 低 |
| 人可读性 | 好 | 差 | 差 | 好 |
| 适用场景 | 轻量级 API | 高性能服务间 | 复杂系统 | Web API |
七、实际应用场景
7.1 区块链领域
以太坊、比特币等区块链节点通常采用 JSON-RPC 暴露 RPC 接口,供钱包、客户端调用。
7.2 Web3 生态
MetaMask、Web3.js 等库基于 JSON-RPC 与以太坊节点通信。
7.3 微服务通信
轻量级微服务架构中的内部服务通信。
7.4 物联网设备通信
设备与服务器交互的简轻通信协议。
八、常见实现陷阱与优化
8.1 需要注意的问题
1. 参数类型转换
1
JSON 中的所有数字都是浮点数,需要确保整数参数正确转换
2. 大数字精度问题
1
2
JSON 中无法准确表示超大整数(>2^53)
解决方案:使用字符串表示大数字
3. 并发请求管理
1
2
同时发送多个请求时,需要正确关联请求与响应
通过 id 字段精确匹配是关键
4. 错误处理规范
1
2
自定义错误码应避免与标准错误码冲突
建议使用 -32000 到 -32099 范围内的值
8.2 性能优化建议
- 连接复用:使用持久连接而非每次新建
- 批量请求:合并多个小请求为一个批量请求
- 异步处理:采用非阻塞模式处理多个并发请求
- 缓存策略:对幂等方法结果进行缓存
- 超时控制:设置合理的请求超时时间
九、总结
JSON-RPC 通过简单而强大的请求-响应模式,提供了轻量级的 RPC 解决方案。其核心优势在于:
- 规范统一:明确的协议定义保证互操作性
- 易于实现:基于 JSON 文本格式,降低实现复杂度
- 灵活传输:可运行在多种传输层之上
- 易于调试:人可读的 JSON 格式便于开发和测试
无论在区块链、Web3、微服务还是物联网领域,JSON-RPC 都展现了其作为轻量级通信协议的价值。深入理解其核心原理和实现细节,对构建分布式系统大有裨益。
参考资源
- JSON-RPC 2.0 规范
- 以太坊 JSON-RPC 文档
- Web3.js、ethers.js 等库的源码实现
本文由作者按照 CC BY 4.0 进行授权