这几天一直在死磕MindX2的 WebStocket 通信问题,但一直没有找到满意的方案。偶然间看到了JSON-RPC 这个大宝贝,感觉就像是拨开云雾见青天,用法简直与 LLM 的 Tools Call 一样,最终也将它整合到了 gort 项目中作为MindX2的通信基础,也特意将相关资料整理了一遍与君共享。
JSON-RPC 2.0 是一种轻量级、无状态且与传输层无关的远程过程调用(RPC)协议,核心设计目标是通过极简的 JSON 数据格式实现跨语言、跨环境的高效远程方法调用(4)。作为 RPC 家族的轻量化代表,它在保持语法简单、解析高效的同时,提供了标准化的错误处理和双向通信能力,既适配微服务架构的轻量通信需求,也能通过 WebSocket 等全双工协议支撑实时场景下的服务端主动推送。本文将从协议理论基础、双向实时通信与微服务场景的应用实践、主流 RPC/API 协议对比及 Python 落地实现等维度,全面阐述 JSON-RPC 2.0 的技术价值与适用边界。
1. JSON-RPC 2.0 协议理论基础
1.1 核心定义与设计原则
JSON-RPC 2.0 的核心是 "远程过程调用" 的语义抽象:允许客户端像调用本地函数一样发起远程请求,服务端通过标准化流程处理并返回结果 ------ 这种设计本质是将分布式节点的交互,转化为开发者熟悉的 "函数调用" 模式,大幅降低了跨节点通信的认知复杂度(4)。其官方规范仅有千余字,所有约束均围绕 "极简、通用、无依赖" 三大原则展开:
- 极简性 :仅定义请求、响应、通知三类核心消息结构,无额外字段或扩展约束,甚至一个基础的加法调用请求仅需数十字节的 JSON 数据,人眼可直接阅读调试,无需额外工具解析(4)。
- 传输无关性 :协议本身不绑定任何传输层,可基于 HTTP、WebSocket、TCP Socket 甚至进程间管道(stdio)运行 ------ 例如以太坊节点默认使用 HTTP 传输 JSON-RPC,而 Motrix 下载管理器则通过 WebSocket 实现实时状态推送,这种灵活性让它能适配从浏览器到嵌入式设备的几乎所有通信场景(4)。
- 无状态性 :每个请求都是自包含的独立单元,服务端无需存储客户端的会话状态或上下文信息。这意味着服务端节点可以水平扩展至数千台,无需担心状态同步的开销,天然适配云原生架构的弹性需求(4)。
- 语言中立性 :依赖 JSON 这一现代编程语言的通用数据格式 ------ 无论是 Python、JavaScript 这类动态语言,还是 Java、Go 这类静态语言,都能通过原生或第三方库快速解析 JSON,真正实现 "一次定义,多语言兼容"(4)。
1.2 系统原理与通信模型
JSON-RPC 2.0 的通信模型围绕 "消息交换" 展开,其核心是标准化的消息结构与极简的交互流程,所有节点的行为都被规范严格约束,确保不同实现之间的兼容性。
1.2.1 消息类型与结构
JSON-RPC 2.0 定义了三类核心消息,所有字段的含义、类型和可选性均有明确规范,任何不符合规范的消息都会被服务端判定为无效请求。
请求对象(Request Object)
请求对象是客户端发起远程调用的唯一格式,用于指定要调用的方法、参数和请求标识。一个合法的请求必须包含以下字段:
jsonrpc:字符串类型,必须严格等于"2.0",用于标识协议版本 ------ 这是 2.0 版本与 1.0 版本的核心区分标志,1.0 版本无此字段,可能导致跨版本兼容问题(4)。method:字符串类型,指定要调用的远程方法名。规范特别约定:以rpc.开头的方法名(如rpc.subscribe)为协议内部保留方法,禁止用户自定义使用,例如rpc.discover通常用于服务端方法列表的自动发现(4)。params:可选字段,支持数组或对象类型 ------ 数组用于按位置传递参数(如[1, 2]对应加法函数的两个入参),对象用于按名称传递参数(如{"minuend": 42, "subtrahend": 23}),两种方式不可混合使用,否则会触发参数无效错误(4)。id:可选字段,支持字符串、数字或null类型,由客户端生成唯一值,用于关联请求与响应。服务端处理完成后,会在响应中带回相同的id,确保异步场景下的请求 - 响应配对不会错乱。需要注意的是,若id为null或省略,则该请求会被视为 "通知",服务端不会返回任何响应(4)。
请求对象的设计兼顾了灵活性和严谨性:按名称传参的方式让接口具备更强的扩展性 ------ 即使后续方法新增参数,旧客户端只需传递已有参数即可正常调用,无需修改代码;而id字段的存在,则为异步调用提供了可靠的上下文关联机制。
响应对象(Response Object)
响应对象是服务端对请求的唯一合法返回格式,必须与对应的请求id完全匹配。其核心字段包括:
jsonrpc:同样必须严格等于"2.0",与请求版本保持一致,避免版本协商的额外开销(4)。result:成功响应时的必填字段,承载方法调用的返回结果,具体类型由方法逻辑决定 ------ 例如加法方法可能返回数字,用户查询方法可能返回对象(4)。error:错误响应时的必填字段,承载标准化的错误信息,具体结构将在 "错误处理" 部分详细说明(4)。id:必填字段,必须与请求对象的id完全一致;若请求本身无效(如 JSON 解析失败),则id需设为null,告知客户端该响应无法关联到任何合法请求(4)。
规范强制要求:result和error字段必须且只能存在一个 ------ 即使方法逻辑返回null,也需通过result: null而非error字段传递,这一约束避免了响应解析的歧义,让客户端能快速判断请求状态。
通知对象(Notification Object)
通知是一类特殊的请求对象:唯一的区别是省略 id字段 。规范明确规定,服务端收到通知后无需返回任何响应 ------ 无论处理成功还是失败,客户端都不会收到反馈(4)。
这种设计特别适用于 "客户端无需关心结果" 的场景:例如日志上报、状态同步、用户行为埋点等。比如在微服务架构中,订单服务完成支付后,可通过通知向消息队列发送事件,无需等待队列的确认响应,从而减少同步等待的开销,提升系统吞吐量。
1.2.2 错误处理机制
JSON-RPC 2.0 定义了完善的标准化错误处理机制,所有错误响应都需通过error对象返回,该对象包含三个核心字段:
code:整数类型错误码,用于标识错误类型,规范将 - 32768 至 - 32000 的范围预留为协议级错误,-32000 至 - 32099 为实现级错误,其余范围可由应用自定义(4)。message:字符串类型的简短错误描述,需简洁清晰,例如 "Parse error" 或 "Method not found",方便开发者快速定位问题类型(4)。data:可选字段,用于携带额外的错误详情,例如参数校验失败时的具体字段、数据库连接异常的堆栈信息等,帮助开发者排查具体问题(4)。
常见的标准错误码如下:
-32700(Parse error):服务端无法解析请求的 JSON 格式,例如客户端发送的 JSON 存在语法错误(如缺少闭合引号),此时服务端无法识别请求的具体内容,只能返回该错误(4)。-32600(Invalid Request):请求结构合法,但不符合 JSON-RPC 2.0 的规范约束,例如缺少method字段、jsonrpc版本错误,或同时存在result和error字段(4)。-32601(Method not found):请求的method不存在或被服务端禁用,例如客户端调用了未注册的userService.login方法(4)。-32602(Invalid params):参数格式或类型不匹配,例如加法方法期望两个数字,但客户端传递了字符串,或按名称传参时缺少必填字段(4)。-32603(Internal error):服务端处理请求时发生未预期的异常,例如数据库连接失败、代码逻辑抛出未捕获的异常等(4)。
标准化错误码的设计,让不同语言、不同框架的 JSON-RPC 实现能共享一套统一的错误处理逻辑 ------ 例如前端可以根据code字段,自动弹出对应的错误提示;监控系统可以基于code统计错误类型的分布,快速定位系统瓶颈。
1.2.3 交互流程
JSON-RPC 2.0 的基础交互流程分为四个核心步骤,所有步骤均有规范约束,确保通信的可靠性:
- 请求发起 :客户端构造符合规范的请求对象,通过选定的传输层(如 HTTP POST 或 WebSocket)发送给服务端。例如,一个调用
subtract方法的请求可能是:
json
{
"jsonrpc": "2.0",
"method": "subtract",
"params": [42, 23],
"id": 1
}
其中params为数组,按位置传递了被减数和减数(4)。
- 请求解析 :服务端首先验证请求的基本格式:检查
jsonrpc字段是否为2.0、method字段是否存在、参数类型是否匹配。若验证失败,服务端会立即返回对应的标准错误响应,终止请求处理(4)。 - 方法调用 :服务端根据
method字段匹配对应的本地函数,将params中的参数传递给函数执行。若params是对象,服务端会自动将其转换为函数的关键字参数;若为数组,则转换为位置参数(4)。 - 响应返回 :服务端将函数执行结果或错误信息封装为响应对象,通过同一传输层返回给客户端。例如,上述
subtract请求的成功响应为:
json
{
"jsonrpc": "2.0",
"result": 19,
"id": 1
}
响应的id与请求完全一致,确保客户端能正确关联结果(4)。
对于通知请求,流程会在 "方法调用" 后终止 ------ 服务端不会返回任何响应,即使方法执行失败,客户端也无法获取错误信息,因此通知仅适用于非关键场景。
1.2.4 批量调用机制
JSON-RPC 2.0 支持批量调用:客户端可以将多个请求对象放入一个 JSON 数组中,一次性发送给服务端,服务端会并行处理这些请求,并将结果按请求顺序返回为一个响应数组(4)。
这一机制的核心优势是减少网络往返次数(RTT):例如,客户端需要调用getUserInfo、getOrderList和getSystemConfig三个方法,若单独发送需 3 次网络请求,而批量调用仅需 1 次,在微服务场景中可将吞吐量提升 30% 以上(256)。
需要注意的是,批量调用中的通知请求不会生成对应的响应项 ------ 即使数组中有 10 个请求,其中 3 个是通知,服务端也只会返回 7 个响应项。同时,服务端会按请求的顺序返回响应,客户端可通过id字段匹配对应的请求,无需担心响应顺序错乱(4)。
一个典型的批量调用请求示例如下:
json
[
{"jsonrpc": "2.0", "method": "sum", "params": [1, 2, 4], "id": "1"},
{"jsonrpc": "2.0", "method": "notify hello", "params": [7]},
{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": "2"}
]
对应的响应数组会包含sum和subtract的结果,但不会包含notify_hello的响应(4)。
2. 双向实时通信场景下的 JSON-RPC 2.0
2.1 实时通信的核心需求
实时通信场景(如即时通讯、在线协作、实时数据推送)对协议的要求集中在四个维度,而这些需求恰好与 JSON-RPC 2.0 的设计特性高度契合:
- 低延迟 :消息从发送到接收的时间需控制在毫秒级,例如在线股票行情推送,延迟超过 100ms 就会影响用户体验,甚至导致交易决策失误(16)。
- 全双工 :客户端和服务端需能在同一连接上同时发送和接收数据,而非传统 HTTP 的 "请求 - 响应" 单向模式 ------ 例如在线聊天室中,用户发送消息的同时,也能接收其他用户的消息(16)。
- 可靠性 :消息需按序到达,不能出现重复或丢失 ------ 例如在线协作文档中,用户的编辑操作需按时间顺序应用,否则会导致文档内容混乱(16)。
- 轻量级 :协议本身的开销需足够小,避免占用过多带宽,尤其在物联网场景中,设备的带宽资源通常有限(16)。
传统的 HTTP 协议无法满足这些需求:它是单向的,每次请求都需要建立连接(即使开启 Keep-Alive,也存在头部开销),且服务端无法主动向客户端推送数据。因此,实时通信场景通常需要依赖 WebSocket 等全双工协议,而 JSON-RPC 2.0 则为其提供了标准化的应用层语义。
2.2 JSON-RPC 2.0 的适配方案
JSON-RPC 2.0 本身不提供传输层能力,但通过与 WebSocket 协议的结合,可完美实现双向实时通信。WebSocket 是 HTML5 引入的全双工通信协议,通过一次 HTTP 握手将连接升级为 TCP 长连接,此后客户端和服务端可在同一连接上双向发送数据,无额外请求头开销,帧头大小仅 2-14 字节,远小于 HTTP 请求的头部开销(通常数百字节)(16)。
2.2.1 技术原理:WebSocket 传输
JSON-RPC 2.0 over WebSocket 的核心逻辑是 "协议复用":WebSocket 提供全双工的传输通道,JSON-RPC 2.0 提供标准化的请求 - 响应 / 通知语义。其具体交互流程如下:
- 连接建立 :客户端通过 HTTP 请求发起 WebSocket 握手,请求头中需包含
Upgrade: websocket和Sec-WebSocket-Protocol: jsonrpc字段,告知服务端要升级为 WebSocket 连接,并使用 JSON-RPC 2.0 作为应用层协议(28)。 - 双向通信:连接建立后,客户端和服务端可通过同一连接双向发送 JSON-RPC 消息 ------ 客户端可以调用服务端的方法,服务端也可以通过通知或请求主动向客户端发送数据。例如,服务端可以通过通知向客户端推送实时日志:
json
{
"jsonrpc": "2.0",
"method": "logUpdate",
"params": {
"level": "info",
"content": "user login success"
}
}
该消息没有id字段,属于通知,客户端无需返回响应(243)。
-
连接维护 :通过心跳机制维持连接活跃性 ------ 客户端定期发送心跳请求(如调用
ping方法),服务端返回pong响应;若客户端在指定时间内未收到响应,则判定连接断开,触发重连逻辑。心跳间隔通常设置为 30 秒,需小于中间节点(如 Nginx)的超时时间(默认 60 秒),避免连接被中间节点主动断开(90)。 -
连接关闭 :客户端或服务端可通过发送关闭帧主动断开连接,关闭码需遵循 WebSocket 标准(如 1000 表示正常关闭,1001 表示端点离开),便于排查连接断开的原因(38)。
2.2.2 核心优势
在双向实时通信场景中,JSON-RPC 2.0 相比其他协议(如 Socket.IO、原生 WebSocket)具有不可替代的优势:
- 标准化语义 :相比原生 WebSocket 的 "原始数据传输",JSON-RPC 2.0 提供了统一的请求 - 响应模型和错误处理机制。例如,原生 WebSocket 需要开发者手动设计消息格式(如
{"type": "request", "data": ...}),而 JSON-RPC 2.0 的规范已明确了所有消息结构,不同客户端和服务端的实现可以无缝兼容,无需额外协商格式(4)。 - 轻量级开销 :JSON-RPC 2.0 的消息头极小,空请求仅需约 50 字节,而 Socket.IO 的空消息至少携带 20 字节的元数据(如
42["msg",{"a":1}]),且 Socket.IO 会额外封装事件名称等信息,实际开销更高(79)。 - 跨平台兼容 :支持浏览器、Node.js、移动应用等多种平台,且无需修改协议逻辑 ------ 例如,Web 前端可以通过
WebSocketAPI 直接连接,Python 后端可以通过websockets库处理连接,双方使用完全一致的 JSON-RPC 消息格式(4)。 - 成熟的库支持 :主流语言都有稳定的 JSON-RPC over WebSocket 库,例如 Python 的
jsonrpc-websocket、JavaScript 的rpc-websockets,这些库已内置心跳重连、错误处理等功能,开发者无需重复实现(90)。
2.2.3 实际应用案例
JSON-RPC 2.0 在双向实时通信场景的落地案例广泛,以下是两个典型场景:
- 即时通讯 :部分轻量级 IM 系统采用 JSON-RPC 2.0 + WebSocket 实现核心通信 ------ 客户端发送消息时调用
sendMessage方法,服务端收到后通过通知向目标客户端推送消息。这种方式既简化了协议设计,又能利用 JSON-RPC 的标准化错误处理,快速定位消息发送失败的原因(如用户未登录、目标用户不存在)(103)。 - 下载管理器实时状态推送 :Motrix 下载管理器采用 "HTTP + WebSocket" 的双传输策略:常规任务管理(如添加下载任务)使用 HTTP 传输,确保可靠性;实时进度推送使用 WebSocket + JSON-RPC 2.0,服务端通过通知主动向客户端推送下载进度、速度等信息,客户端无需轮询,大幅减少了网络开销和服务端压力(97)。
- 大模型 Agent 协同 :字节跳动的 MCP(模型上下文协议)采用 JSON-RPC 2.0 作为核心通信协议,实现大模型与外部工具(如代码解释器、搜索引擎)的双向交互。大模型作为客户端调用工具的方法,工具作为服务端返回结果,同时服务端可以通过通知主动向大模型推送中间状态(如代码执行进度),适配大模型场景的异步交互需求(162)。
2.3 挑战与应对策略
尽管 JSON-RPC 2.0 适配实时通信场景,但仍存在一些固有挑战,需通过额外机制解决:
- 数据安全性 :WebSocket 本身不提供加密,敏感数据在传输过程中可能被窃听或篡改。应对方案是使用 TLS 1.3 加密连接(即
wss://协议),并在应用层添加身份验证 ------ 例如,客户端在连接建立时发送 JWT Token,服务端验证 Token 的有效性后才允许后续通信(90)。 - 传输效率 :JSON 的文本格式在处理大量二进制数据(如图片、音频)时,序列化开销会显著高于二进制协议(如 MessagePack)。应对方案是在传输二进制数据时,先将其编码为 Base64,或在客户端和服务端协商使用 MessagePack 等二进制格式替代 JSON------ 部分 JSON-RPC 库(如
@rfkit/json-rpc-websocket)已内置对 MessagePack 的支持,可将序列化开销降低约 40%(90)。 - 连接管理 :长连接可能因网络波动或服务器重启中断,导致消息丢失。应对方案是实现自动重连(采用指数退避算法,避免频繁重连压垮服务器)和消息重传机制 ------ 客户端可以缓存未确认的消息,重连成功后重新发送;同时服务端可以维护消息的幂等性,确保重复发送的消息不会被多次处理(90)。
3. 微服务架构中的 JSON-RPC 2.0
微服务架构强调服务解耦、独立部署和轻量通信,而 JSON-RPC 2.0 的设计哲学恰好与这些需求高度契合 ------ 它提供了足够的语义保障,同时又不会引入额外的复杂度,成为微服务内部通信的轻量化选择。
3.1 微服务场景的核心需求
根据 2026 年云原生微服务的演进趋势,现代微服务架构对通信协议的要求集中在以下五点,而这些要求正是 JSON-RPC 2.0 的设计优势所在:
- 服务解耦 :服务间通过标准化接口通信,无需依赖具体实现细节 ------ 例如,订单服务只需知道用户服务的
getUserInfo方法签名,无需关心其内部是用 Python 还是 Java 实现(119)。 - 独立部署 :服务升级或变更时,不影响其他服务的正常运行 ------ 这要求协议具备良好的向后兼容性,例如新增参数时不影响旧客户端的调用(119)。
- 跨语言通信 :支持不同编程语言实现的服务间交互 ------ 例如,Python 服务调用 Java 服务,或 Go 服务调用 PHP 服务(119)。
- 轻量高效 :协议开销小,解析速度快,适配高并发场景 ------ 例如,电商平台的订单服务在大促期间需处理每秒数千次的调用,协议开销直接影响系统吞吐量(119)。
- 可观测性 :支持监控、追踪和错误排查 ------ 例如,能快速定位服务调用失败的原因,统计方法调用的延迟和成功率(119)。
3.2 应用优势
JSON-RPC 2.0 在微服务场景的核心优势可归纳为四点,每一点都直接命中微服务的痛点:
- 无状态性与水平扩展 :服务端无需维护会话状态,可根据流量动态扩缩容 ------ 例如,在 Kubernetes 集群中,JSON-RPC 服务可以通过 HPA(水平 Pod 自动扩缩容)快速增加实例数,无需担心状态同步的问题,这是有状态协议(如 HTTP Session)无法比拟的优势(4)。
- 跨语言兼容性 :基于 JSON 格式,所有现代编程语言都能原生解析,无需生成额外代码 ------ 例如,Python 服务可以通过
json模块直接处理请求,Java 服务可以通过Jackson库解析,无需像 gRPC 那样通过 IDL 生成代码,大幅降低了跨语言通信的门槛(4)。 - 批量请求支持 :减少网络往返次数,提升高并发场景下的吞吐量 ------ 例如,商品详情页需要调用用户服务、商品服务和订单服务三个接口,若使用 JSON-RPC 的批量调用,仅需 1 次网络请求即可获取所有数据,相比单独调用 3 次,延迟可降低约 60%(256)。
- 开发与调试效率 :JSON 格式具有良好的可读性,无需额外工具即可直接查看请求内容 ------ 例如,开发者可以通过 Chrome DevTools 的 Network 面板,直接查看 JSON-RPC 的请求和响应,快速定位参数错误或方法调用失败的原因,这比二进制协议(如 gRPC 的 Protobuf)更易于调试(97)。
3.3 实际落地案例
JSON-RPC 2.0 在微服务场景的落地案例同样广泛,以下是两个典型场景:
- 多语言微服务协同 :某企业采用 Spring Boot(Java)+ Hyperf(PHP)的多语言微服务架构,使用 Nacos 作为服务发现,JSON-RPC 2.0 作为服务间通信协议。Java 服务通过
jsonrpc-spring-boot-starter暴露接口,PHP 服务通过 Hyperf 的 JSON-RPC 客户端调用,实现了跨语言的服务协同 ------ 例如,订单服务(PHP)调用用户服务(Java)的getUserInfo方法,仅需配置服务名称和方法签名,无需额外适配代码(113)。 - RabbitMQ 集成实现高并发 :Python-jrpc 框架支持与 RabbitMQ 的集成,通过消息队列实现 JSON-RPC 请求的异步处理和负载均衡。服务端将请求放入 RabbitMQ 队列,多个消费者进程从队列中获取请求并处理,这种方式可以支撑每秒数千次的并发请求,同时避免了服务端过载 ------ 例如,用户服务的
getUserInfo方法被调用时,请求会被放入队列,由多个消费者进程并行处理,提升了系统的并发能力(299)。
3.4 限制与应对方案
JSON-RPC 2.0 在微服务场景的主要限制集中在性能和生态集成方面,但这些限制都有成熟的应对方案:
- 性能瓶颈 :JSON 的序列化和反序列化速度比二进制协议慢 ------ 例如,Protobuf 的序列化速度是 JSON 的 5-10 倍,数据体积是 JSON 的 1/3~1/5。在 1000 次连续调用的测试中,gRPC 的平均耗时为 3.2ms,而 JSON-RPC 的平均耗时为 8.7ms,性能差距约 2.7 倍(261)。应对方案是:核心服务间通信使用 gRPC,内部管理类服务(如配置查询、日志服务)使用 JSON-RPC,兼顾性能和开发效率;或使用更高效的 JSON 解析库(如 Python 的
ujson),将序列化开销降低约 30%(67)。 - 生态集成度 :相比 gRPC 等主流微服务协议,JSON-RPC 的服务治理生态(如服务发现、负载均衡、熔断降级)支持度较低 ------ 例如,Istio 默认不支持 JSON-RPC 的方法级路由,只能通过 HTTP 路径或头部进行路由(149)。应对方案是:通过服务网格或网关间接支持 ------ 例如,使用 Nacos 或 Consul 实现服务发现,在网关层配置路由规则;或使用第三方库(如
python-jsonrpc-lib)扩展服务治理功能(113)。 - 强类型缺失 :JSON 是弱类型格式,参数类型错误只能在运行时发现 ------ 例如,客户端传递字符串类型的年龄,服务端在处理时才会抛出
Invalid params错误,无法在编译时提前发现(195)。应对方案是使用 OpenRPC 规范定义接口契约 ------OpenRPC 是专为 RPC 设计的接口描述规范,类似 OpenAPI,可生成强类型客户端代码,并支持参数校验,将类型错误提前到开发阶段(142)。
4. 与其他 RPC/API 协议的对比
为了更清晰地展示 JSON-RPC 2.0 的技术定位,将其与当前主流的 RPC/API 协议进行多维度对比,覆盖设计定位、性能、生态等核心指标。
4.1 对比维度说明
本次对比选取了以下核心维度,覆盖协议的设计、性能、生态和适用场景:
- 设计定位:协议的核心设计目标和适用场景,决定了其在架构中的角色。
- 数据格式:序列化格式,直接影响传输效率和可读性。
- 传输协议:底层依赖的传输层协议,影响连接复用、双向通信等能力。
- 性能:序列化速度、数据体积和延迟,是高并发场景的关键指标。
- 接口定义:是否需要 IDL(接口定义语言),影响开发效率和强类型支持。
- 生态支持:第三方库、服务网格、监控工具的支持程度,影响落地成本。
- 适用场景:协议最适合的业务场景,帮助开发者快速选型。
4.2 详细对比表
| 特性 | JSON-RPC 2.0 | gRPC | XML-RPC | Thrift | RESTful API |
|---|---|---|---|---|---|
| 设计定位 | 轻量级 RPC,极简主义 | 高性能 RPC,云原生标准 | 传统 XML RPC,已淘汰 | 多协议 RPC,跨语言高性能 | 资源型 API,标准化接口 |
| 数据格式 | JSON(文本,易读) | Protobuf(二进制,高效) | XML(文本,冗余) | Thrift Binary(二进制 / 多格式) | JSON/XML(文本,易读) |
| 传输协议 | 任意(HTTP/1.1、WebSocket、TCP) | HTTP/2(多路复用、双向流) | HTTP/1.1 | 自定义 TCP/HTTP | HTTP/1.1(无状态) |
| 性能 | 中等(1000 次调用耗时 8.7ms) | 极高(1000 次调用耗时 3.2ms) | 低(解析慢、冗余大) | 高(二进制协议,接近 gRPC) | 中等(HTTP 头开销大) |
| 接口定义 | 无(可选 OpenRPC) | 强 IDL(.proto) | 无 | 强 IDL(.thrift) | 无(可选 OpenAPI) |
| 生态支持 | 轻量,第三方库为主 | 丰富,云原生工具链完备 | 老旧,几乎无更新 | 中等,跨语言支持好 | 极其丰富,浏览器原生支持 |
| 适用场景 | 微服务内部通信、实时通知、快速原型 | 微服务核心链路、高并发场景、跨语言通信 | 老旧系统兼容、简单接口 | 分布式系统、大数据传输、跨语言通信 | 对外 API、前端后端交互、资源型服务 |
4.3 关键差异分析
4.3.1 与 gRPC 对比
gRPC 是 Google 开源的高性能 RPC 框架,基于 HTTP/2 和 Protobuf,是云原生微服务的标准通信协议。两者的核心差异如下:
- 性能 :gRPC 的性能显著优于 JSON-RPC------Protobuf 的序列化速度是 JSON 的 5-10 倍,数据体积是 JSON 的 1/3~1/5。在 1000 次连续调用的测试中,gRPC 的平均耗时为 3.2ms,而 JSON-RPC 的平均耗时为 8.7ms,性能差距约 2.7 倍(261)。
- 接口定义 :gRPC 使用强 IDL(.proto)定义接口,需提前生成代码,支持强类型检查 ------ 例如,若参数类型不匹配,在编译阶段就会报错;而 JSON-RPC 无需 IDL,参数类型检查只能在运行时进行(217)。
- 生态 :gRPC 的生态支持更丰富,内置双向流、头部压缩、负载均衡等功能,且与云原生工具(如 Istio、Prometheus)深度集成 ------ 例如,Istio 支持 gRPC 的方法级路由和监控,而 JSON-RPC 需要通过网关间接支持(149)。
- 适用场景 :gRPC 适合微服务核心链路、高并发场景;JSON-RPC 适合轻量级内部通信、快速原型开发,或对可读性要求较高的场景(如大模型 Agent 交互)(217)。
4.3.2 与 XML-RPC 对比
XML-RPC 是 JSON-RPC 的 "前辈",基于 XML 格式,是早期 RPC 协议的代表。JSON-RPC 2.0 在多个维度全面超越 XML-RPC:
- 数据体积 :JSON 的冗余度比 XML 低约 40%------ 例如,一个简单的加法请求,XML-RPC 需要约 1.8KB 的载荷,而 JSON-RPC 仅需约 1.2KB,数据体积减少约 33%(191)。
- 解析速度 :JSON 的解析速度比 XML 快约 50%------XML 需要完整的 DOM 解析,而 JSON 可以通过流式解析快速处理,尤其在嵌入式设备或低性能服务器上,解析速度的差异更为明显(191)。
- 特性支持 :JSON-RPC 2.0 支持批量请求、通知机制和标准化错误码,而 XML-RPC 仅支持简单的请求 - 响应,且错误处理机制不统一 ------ 例如,XML-RPC 的错误码由开发者自定义,不同实现之间无法兼容(4)。
- 适用场景 :XML-RPC 仅适合老旧系统兼容,新系统应优先选择 JSON-RPC 2.0(191)。
4.3.3 与 Thrift 对比
Thrift 是 Facebook 开源的多协议 RPC 框架,支持多种序列化格式和传输协议,兼顾性能和灵活性。两者的核心差异如下:
- 性能:Thrift 的性能优于 JSON-RPC------ 在单服务器吞吐量测试中,Thrift 的 QPS 约为 25000,而 JSON-RPC 的 QPS 约为 8000,吞吐量差距约 3 倍;延迟方面,Thrift 的平均延迟约为 1.8ms,JSON-RPC 约为 3.2ms。
- 灵活性:Thrift 支持多种序列化格式(如 Binary、Compact)和传输协议(如 TCP、HTTP),可根据场景调整 ------ 例如,在高并发场景下使用 Binary 格式 + TCP 传输,在需要可读性的场景下使用 JSON 格式 + HTTP 传输;而 JSON-RPC 仅支持 JSON 格式,传输协议的灵活性也不如 Thrift。
- 开发效率:JSON-RPC 无需 IDL,开发更简单 ------ 例如,开发者只需定义本地函数,即可通过 JSON-RPC 暴露为远程方法;而 Thrift 需要编写 IDL 文件,生成代码后才能开发,增加了额外的复杂度。
- 适用场景:Thrift 适合分布式系统、大数据传输;JSON-RPC 适合轻量级微服务、快速原型开发。
4.3.4 与 RESTful API 对比
RESTful API 是当前最流行的 API 设计风格,基于 HTTP 协议,以 "资源" 为核心。两者的核心差异如下:
- 语义模型 :JSON-RPC 是 "方法调用" 语义 ------ 例如,调用
userService.login方法,传递用户名和密码,关注的是 "动作";而 RESTful API 是 "资源操作" 语义 ------ 例如,POST/users/login,关注的是 "资源(用户)的操作(登录)"。 - 传输效率 :JSON-RPC 仅使用 POST 方法,所有请求通过单一端点,无需维护多个 URL------ 例如,所有方法调用都发送到
/rpc端点;而 RESTful API 需要为每个资源定义不同的 URL(如/users、/orders),并使用不同的 HTTP 方法(GET/POST/PUT/DELETE),增加了 URL 管理的复杂度(4)。 - 批量支持 :JSON-RPC 原生支持批量请求,可在一次调用中执行多个方法;而 RESTful API 需要多次请求,或通过自定义批量接口实现,增加了网络开销(4)。
- 适用场景:JSON-RPC 适合微服务内部通信、实时通知;RESTful API 适合对外 API、前端后端交互,或对资源操作有明确需求的场景。
5. Python 实现指南与代码示例
Python 作为胶水语言,在微服务和实时场景中应用广泛,其生态拥有多个稳定的 JSON-RPC 2.0 实现库。本节将介绍主流库的特性,并提供 WebSocket 双向通信和微服务场景的可运行示例。
5.1 主流 Python 库特性对比
根据 2026 年 Python JSON-RPC 库的使用情况,以下是四个主流库的特性对比,覆盖传输支持、异步能力、参数验证等核心指标:
| 库名称 | 传输支持 | 异步支持 | 参数验证 | 服务发现 | 适用场景 |
|---|---|---|---|---|---|
python-jsonrpc-lib |
HTTP/1.1、WebSocket | 是 | 是(Pydantic) | 否 | 微服务、实时通信 |
aiohttp-rpc |
HTTP/1.1、WebSocket | 是 | 否 | 否 | 异步服务、实时通信 |
jsonrpcserver |
HTTP/1.1 | 是 | 否 | 否 | 简单 RPC 服务 |
fastapi-jsonrpc |
HTTP/1.1、WebSocket | 是 | 是(Pydantic) | 否 | FastAPI 生态、微服务 |
其中,python-jsonrpc-lib是 2026 年最受欢迎的 JSON-RPC 库,支持 Pydantic 参数验证和 WebSocket 传输,且与 FastAPI、Flask 等主流 Web 框架兼容,适合大多数场景。
5.2 双向实时通信示例(WebSocket)
本示例使用python-jsonrpc-lib和websockets库实现基于 WebSocket 的双向实时通信,包含服务端主动推送通知的功能。
5.2.1 服务端实现
服务端需要实现三个核心功能:处理客户端的ping请求、主动向客户端推送时间通知、管理客户端连接。
python
import asyncio
import json
import websockets
from datetime import datetime
from python_jsonrpc_lib import JSONRPCServer, Method
# 创建JSON-RPC服务器实例
rpc_server = JSONRPCServer()
# 存储所有连接的客户端
clients = set()
# 注册RPC方法:处理客户端的ping请求
@Method
async def ping() -> str:
return "pong"
# 注册RPC方法:客户端订阅时间通知
@Method
async def subscribe_time() -> str:
# 获取当前连接的客户端
client = asyncio.current_task().get_name()
if client not in clients:
clients.add(client)
print(f"客户端 {client} 订阅时间通知成功")
return "subscribed"
# 主动推送时间通知的任务
async def push_time():
while True:
# 每隔5秒推送一次
await asyncio.sleep(5)
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 构造JSON-RPC通知
notification = {
"jsonrpc": "2.0",
"method": "time_update",
"params": {"time": current_time}
}
# 向所有客户端推送
if clients:
await asyncio.gather(
[client.send(json.dumps(notification)) for client in clients],
return_exceptions=True
)
print(f"已推送时间通知: {current_time}")
# 处理WebSocket连接
async def handle_websocket(websocket, path):
# 将当前连接的客户端添加到集合
clients.add(websocket)
try:
# 启动时间推送任务
asyncio.create_task(push_time())
# 处理客户端的JSON-RPC请求
async for message in websocket:
try:
# 解析请求
request = json.loads(message)
# 处理请求并获取响应
response = await rpc_server.dispatch(request)
# 若响应存在(非通知),则返回给客户端
if response:
await websocket.send(json.dumps(response))
except json.JSONDecodeError:
# 处理JSON解析错误
error = {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": None}
await websocket.send(json.dumps(error))
finally:
# 连接关闭时移除客户端
clients.remove(websocket)
print(f"客户端 {websocket} 断开连接")
# 启动WebSocket服务器
async def main():
async with websockets.serve(handle_websocket, "localhost", 8765):
print("JSON-RPC WebSocket服务器已启动,端口:8765")
await asyncio.Future() # 保持服务器运行
if __name__ == "__main__":
asyncio.run(main())
5.2.2 客户端实现
客户端需要实现三个核心功能:连接到服务端、调用ping方法、订阅时间通知、处理服务端的时间通知。
python
import asyncio
import json
import websockets
from python_jsonrpc_lib import JSONRPCClient
# 处理服务端的通知(如时间更新)
async def handle_notifications(websocket):
async for message in websocket:
try:
data = json.loads(message)
# 判断是否为JSON-RPC通知(无id字段)
if "method" in data and "id" not in data:
if data["method"] == "time_update":
print(f"收到时间通知: {data['params']['time']}")
except json.JSONDecodeError:
print("无效的JSON格式消息")
# 客户端主逻辑
async def main():
uri = "ws://localhost:8765"
async with websockets.connect(uri) as websocket:
# 创建JSON-RPC客户端
client = JSONRPCClient(websocket)
# 调用服务端的ping方法
ping_result = await client.call("ping")
print(f"ping响应: {ping_result}")
# 订阅时间通知
subscribe_result = await client.call("subscribe_time")
print(f"订阅结果: {subscribe_result}")
# 处理服务端的通知
await handle_notifications(websocket)
if __name__ == "__main__":
asyncio.run(main())
5.2.3 代码说明
- 服务端 :通过
websockets.serve启动 WebSocket 服务器,监听 8765 端口;使用JSONRPCServer注册ping和subscribe_time方法;通过push_time任务主动向客户端推送时间通知,通知采用 JSON-RPC 的标准格式(无id字段)。 - 客户端 :通过
websockets.connect连接到服务端;使用JSONRPCClient调用服务端的方法;通过handle_notifications函数处理服务端的通知,判断依据是消息是否包含method字段且无id字段。 - 关键特性 :实现了服务端主动推送和客户端请求的双向通信,错误处理符合 JSON-RPC 2.0 的标准规范 ------ 例如,当客户端发送无效 JSON 时,服务端会返回
-32700(Parse error)错误。
5.3 微服务场景示例(FastAPI + Nacos)
本示例使用fastapi-jsonrpc和nacos-sdk-python实现微服务场景的服务注册与发现,包含服务端和客户端的完整代码。
5.3.1 服务端实现(FastAPI + JSON-RPC)
服务端需要实现两个核心功能:暴露 JSON-RPC 接口、将服务注册到 Nacos。
python
from fastapi import FastAPI
from fastapi_jsonrpc import JSONRPCAPI, method
from pydantic import BaseModel
from nacos import NacosClient, RegisterInstanceParam
import uvicorn
# 初始化FastAPI应用
app = FastAPI()
# 初始化JSON-RPC API
rpc_api = JSONRPCAPI()
# 定义参数模型(用于Pydantic验证)
class AddParams(BaseModel):
a: int
b: int
# 注册RPC方法:加法运算
@method(name="add")
async def add(params: AddParams) -> int:
return params.a + params.b
# 注册RPC方法:获取服务信息
@method(name="get_service_info")
async def get_service_info() -> dict:
return {
"service_name": "jsonrpc-calculator",
"version": "1.0.0",
"description": "基于JSON-RPC的计算器服务"
}
# 将JSON-RPC API挂载到FastAPI应用
app.mount("/rpc", rpc_api)
# Nacos配置
NACOS_SERVER = "localhost:8848"
SERVICE_NAME = "jsonrpc-calculator"
SERVICE_IP = "127.0.0.1"
SERVICE_PORT = 8000
# 注册服务到Nacos
def register_to_nacos():
client = NacosClient(NACOS_SERVER)
# 构造注册参数
param = RegisterInstanceParam(
service_name=SERVICE_NAME,
ip=SERVICE_IP,
port=SERVICE_PORT,
weight=1.0,
ephemeral=True
)
# 注册服务实例
client.register_instance(param)
print(f"服务 {SERVICE_NAME} 已注册到Nacos")
# 启动时注册服务
@app.on_event("startup")
async def startup_event():
register_to_nacos()
if __name__ == "__main__":
uvicorn.run(app, host=SERVICE_IP, port=SERVICE_PORT)
5.3.2 客户端实现(Nacos 服务发现 + JSON-RPC 调用)
客户端需要实现两个核心功能:从 Nacos 获取服务实例、调用服务端的 JSON-RPC 方法。
python
import requests
import json
from nacos import NacosClient
# Nacos配置
NACOS_SERVER = "localhost:8848"
SERVICE_NAME = "jsonrpc-calculator"
# 从Nacos获取服务实例
def get_service_instance():
client = NacosClient(NACOS_SERVER)
# 获取服务的所有实例
instances = client.get_service_instances(SERVICE_NAME)
if not instances:
raise Exception("未找到服务实例")
# 返回第一个健康实例
return instances[0]
# 调用JSON-RPC服务
def call_jsonrpc_service(method, params=None):
# 获取服务实例
instance = get_service_instance()
url = f"http://{instance.ip}:{instance.port}/rpc"
# 构造JSON-RPC请求
request_data = {
"jsonrpc": "2.0",
"method": method,
"params": params or {},
"id": 1
}
# 发送POST请求
response = requests.post(url, json=request_data)
# 解析响应
result = response.json()
if "error" in result:
raise Exception(f"RPC调用错误: {result['error']['message']}")
return result["result"]
if __name__ == "__main__":
try:
# 调用加法方法
add_result = call_jsonrpc_service("add", {"a": 10, "b": 20})
print(f"加法结果: {add_result}")
# 调用获取服务信息的方法
service_info = call_jsonrpc_service("get_service_info")
print(f"服务信息: {service_info}")
except Exception as e:
print(f"调用失败: {e}")
5.3.3 代码说明
- 服务端 :使用
fastapi-jsonrpc快速搭建 JSON-RPC 服务,通过 Pydantic 的AddParams模型实现参数验证 ------ 例如,若客户端传递非整数的a或b,会自动返回-32602(Invalid params)错误;在启动时通过nacos-sdk-python将服务注册到 Nacos,便于客户端发现。 - 客户端 :通过 Nacos 获取服务实例列表,选择健康实例进行调用;使用
requests库发送 JSON-RPC 请求,处理响应并返回结果 ------ 若服务端返回错误,客户端会抛出对应的异常。 - 关键特性:实现了服务注册与发现,参数验证符合 JSON-RPC 2.0 的规范,适配微服务场景的动态扩缩容需求 ------ 例如,当服务端实例数增加时,客户端会自动获取新的实例列表。
5.4 错误处理与参数验证最佳实践
在生产环境中,错误处理和参数验证是保障系统稳定性的核心,以下是基于 Pydantic 的最佳实践:
5.4.1 参数验证
使用 Pydantic 模型定义参数,自动进行类型检查和格式验证 ------ 例如,定义UserCreate模型,包含用户名(长度 3-20)、年龄(≥18)和邮箱(格式验证):
python
from pydantic import BaseModel, EmailStr, Field
from python_jsonrpc_lib import Method
# 定义用户创建的参数模型
class UserCreate(BaseModel):
username: str = Field(..., min_length=3, max_length=20, description="用户名,长度3-20")
age: int = Field(..., ge=18, description="年龄,至少18岁")
email: EmailStr = Field(..., description="邮箱,格式需合法")
# 注册RPC方法:创建用户
@Method
async def create_user(params: UserCreate) -> dict:
# 模拟创建用户的逻辑
return {
"user_id": 123,
"username": params.username,
"age": params.age,
"email": params.email
}
上述代码中,Pydantic 会自动验证参数的类型、长度和格式:若客户端传递的用户名长度小于 3,或年龄小于 18,或邮箱格式无效,会自动返回-32602(Invalid params)错误,并在data字段中包含详细的错误信息(如"username": "ensure this value has at least 3 characters")(274)。
5.4.2 错误映射
将 Pydantic 的ValidationError转换为 JSON-RPC 2.0 的标准错误响应,确保错误格式统一 ------ 例如,在 FastAPI 应用中添加异常处理器:
python
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from pydantic import ValidationError
from python_jsonrpc_lib import JSONRPCError
# 初始化FastAPI应用
app = FastAPI()
# 异常处理器:处理Pydantic的ValidationError
@app.exception_handler(ValidationError)
async def validation_exception_handler(request: Request, exc: ValidationError):
# 构造JSON-RPC错误响应
error = JSONRPCError(
code=-32602, # Invalid params
message="Invalid parameters",
data=exc.errors() # 包含详细的验证错误信息
)
return JSONResponse(
content={"jsonrpc": "2.0", "error": error.dict(), "id": None},
status_code=200
)
该处理器会捕获所有 Pydantic 验证错误,将其转换为 JSON-RPC 2.0 的标准错误响应,确保客户端能收到统一格式的错误信息,便于处理和调试。
5.4.3 自定义错误码
除了标准错误码,还可以定义业务级的错误码(范围 - 32000~-32099),例如用户不存在、权限不足等:
python
from python_jsonrpc_lib import JSONRPCError
# 定义自定义错误码
USER_NOT_FOUND = -32001
PERMISSION_DENIED = -32002
# 注册RPC方法:获取用户信息
@Method
async def get_user(user_id: int) -> dict:
# 模拟用户不存在的场景
if user_id != 123:
raise JSONRPCError(
code=USER_NOT_FOUND,
message="User not found",
data={"user_id": user_id}
)
# 模拟权限不足的场景
if user_id == 456:
raise JSONRPCError(
code=PERMISSION_DENIED,
message="Permission denied",
data={"user_id": user_id}
)
# 模拟用户存在的场景
return {"user_id": 123, "username": "Alice"}
自定义错误码的使用,让错误信息更具业务语义,便于客户端快速定位问题类型 ------ 例如,客户端收到USER_NOT_FOUND错误码时,可以自动提示 "用户不存在",提升用户体验(4)。
6. 总结
JSON-RPC 2.0 是一款 "以简驭繁" 的 RPC 协议:它摒弃了传统 RPC 协议的冗余特性,通过极简的 JSON 格式和标准化的语义,实现了跨语言、跨环境的高效通信。其核心价值在于 "平衡"------ 平衡了性能与开发效率,平衡了轻量级与功能性,平衡了通用性与适配性。
6.1 核心价值总结
- 极简性 :协议规范仅千余字,消息结构清晰,人眼可直接阅读调试,无需额外工具解析。这一特性大幅降低了开发和调试成本,尤其适合快速原型开发或小团队项目 ------ 例如,一个简单的加法调用请求仅需数十字节的 JSON 数据,开发者可以在数分钟内完成服务端和客户端的实现(4)。
- 双向通信能力 :通过 WebSocket 等全双工协议,可实现服务端主动推送,适配实时通信场景的需求。例如,Motrix 下载管理器通过 WebSocket + JSON-RPC 2.0 实现下载进度的实时推送,客户端无需轮询,大幅减少了网络开销和服务端压力(243)。
- 跨语言兼容性 :基于 JSON 格式,所有现代编程语言都能原生解析,无需生成额外代码,真正实现 "一次定义,多语言兼容"。例如,Python 服务可以调用 Java 服务的接口,双方使用完全一致的 JSON-RPC 消息格式,无需额外适配代码(4)。
- 成熟的生态 :主流语言都有稳定的实现库,支持 HTTP、WebSocket 等多种传输协议,且与云原生工具(如 Nacos、Consul)的集成度不断提升 ------ 例如,
python-jsonrpc-lib支持与 FastAPI、Flask 等主流 Web 框架的集成,nacos-sdk-python支持将 JSON-RPC 服务注册到 Nacos,实现服务发现。
6.2 适用场景建议
根据 JSON-RPC 2.0 的特性,以下场景是其最佳选择:
- 双向实时通信:即时通讯、在线协作、实时数据推送(如股票行情、下载进度)等场景,需要服务端主动推送数据,且对协议开销有要求 ------JSON-RPC 2.0 的轻量级和双向通信能力,使其成为这类场景的理想选择。
- 微服务内部通信:轻量级微服务、多语言服务协同等场景,需要快速开发和部署,且对性能的要求不是极端严格 ------ 例如,内部管理类服务(如配置查询、日志服务),使用 JSON-RPC 2.0 可以大幅提升开发效率,同时降低维护成本。
- 快速原型开发:需要快速验证业务逻辑,或团队规模较小的项目 ------JSON-RPC 2.0 无需 IDL,无需生成代码,开发者可以快速实现服务端和客户端的通信,将精力集中在业务逻辑上。
- 大模型 Agent 交互:大模型与外部工具的双向交互场景,需要协议具备良好的可读性和异步支持 ------ 例如,字节跳动的 MCP 协议采用 JSON-RPC 2.0,实现大模型与代码解释器、搜索引擎的交互,开发者可以直接查看请求内容,快速调试工具调用逻辑。
6.3 未来展望
随着云原生和实时应用的普及,JSON-RPC 2.0 的轻量化和灵活性使其仍将在特定场景中发挥重要作用。未来的发展趋势主要集中在以下三个方向:
- 与 WebAssembly(Wasm)的结合:WebAssembly 是一种高性能的字节码格式,可在浏览器和服务器端运行。JSON-RPC 2.0 与 Wasm 的结合,将在保持轻量级的同时提升性能 ------ 例如,使用 Wasm 编写 JSON-RPC 的序列化和反序列化逻辑,可将解析速度提升约 50%,同时保持 JSON 的可读性。
- 服务网格生态的完善 :随着服务网格(如 Istio、Linkerd)的普及,JSON-RPC 的服务治理支持将逐步完善 ------ 例如,Istio 未来可能会支持 JSON-RPC 的方法级路由,允许开发者根据方法名称进行流量拆分或灰度发布,进一步提升 JSON-RPC 在微服务场景的适配性(149)。
- 与 AI Agent 的深度集成:JSON-RPC 2.0 的通知机制和双向通信能力,使其成为大模型 Agent 与外部工具交互的理想协议 ------ 例如,OpenAI 的 Function Call 功能本质上就是基于 JSON-RPC 的语义设计,未来可能会出现更多针对 AI Agent 的 JSON-RPC 扩展库,支持工具发现、异步调用等高级功能。
综上所述,JSON-RPC 2.0 虽然不是性能最强的 RPC 协议,但其极简的设计和良好的灵活性,使其成为特定场景下的最优选择。对于开发者而言,理解 JSON-RPC 2.0 的技术原理和适用边界,将有助于在实际项目中做出更合理的技术选型,提升开发效率和系统稳定性。
**参考资料 **
1\] JSON-RPC 2.0 Specification[https://www.jsonrpc.org/specification](https://link.juejin.cn?target=https%3A%2F%2Fwww.jsonrpc.org%2Fspecification "https://www.jsonrpc.org/specification") \[2\] JSON-RPC 2.0协议详解[https://blog.jianggujin.com/post/19](https://link.juejin.cn?target=https%3A%2F%2Fblog.jianggujin.com%2Fpost%2F19 "https://blog.jianggujin.com/post/19") \[3\] 深入掌握JSON-RPC协议与实战应用-CSDN博客[https://blog.csdn.net/weixin_35749440/article/details/155590028](https://link.juejin.cn?target=https%3A%2F%2Fblog.csdn.net%2Fweixin_35749440%2Farticle%2Fdetails%2F155590028 "https://blog.csdn.net/weixin_35749440/article/details/155590028") \[4\] JSON-RPC 2.0 Specification[https://www.jsonrpc.org/specification](https://link.juejin.cn?target=https%3A%2F%2Fwww.jsonrpc.org%2Fspecification "https://www.jsonrpc.org/specification")