什么是JSON-RPC 2.0,在项目中应该怎么使用

它是什么

JSON-RPC 2.0 是一种超轻量、与传输无关的远程调用协议:用 JSON 表达“方法名 + 参数 → 结果/错误”。可跑在 HTTP、WebSocket、Unix 管道,甚至 stdio 上(很多开发协议如 LSP 就用它)。

报文长这样
• 请求:

{"jsonrpc":"2.0","method":"sum","params":[1,2,3],"id":"42"}

params 可是数组(按位置)或对象(按名),id 用来对应响应(字符串/数字均可)。
• 通知(不需要回应):去掉 id

{"jsonrpc":"2.0","method":"log","params":{"msg":"hi"}}
•	响应(二选一:要么 result,要么 error):
{"jsonrpc":"2.0","result":6,"id":"42"}
{"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found"},"id":"42"}
•	批量:请求或响应都是数组。

常用错误码:
-32700 解析错误、
-32600 非法请求、
-32601 方法不存在、
-32602 参数错误、
-32603 服务器内部错;
-32000~-32099 留给服务端自定义。

什么时候用(和 REST/gRPC 对比)
• 你想要**“方法调用式”接口、低 ceremony、浏览器/脚本语言友好、支持批量/通知**时 → JSON-RPC 很合适。
• 资源/对象语义清晰、需要缓存/幂等/超媒体 → REST 更自然。
• 强类型/高性能/流式、多语言代码生成 → gRPC 更强。

在 FastAPI 中落地(最小实现,支持批量/通知)

pip install fastapi uvicorn httpx

from typing import Any, Dict, Callable, List, Optional
from fastapi import FastAPI, Request, Response
from fastapi.responses import JSONResponseapp = FastAPI()

1) 方法注册表

methods: Dict[str, Callable[..., Any]] = {}def rpc_method(name: str):def deco(fn: Callable[..., Any]):methods[name] = fnreturn fnreturn deco@rpc_method("sum")
def sum_(numbers: List[float]) -> float:return float(sum(numbers))@rpc_method("echo")
def echo(msg: str) -> str:return msg

2) 协议工具

def error(code: int, message: str, _id: Any = None, data: Any = None):e = {"code": code, "message": message}if data is not None:e["data"] = datareturn {"jsonrpc": "2.0", "error": e, "id": _id}def success(result: Any, _id: Any):return {"jsonrpc": "2.0", "result": result, "id": _id}def handle_one(req: Dict[str, Any]) -> Optional[Dict[str, Any]]:# 通知:没有 id -> 不返回_id = req.get("id", None)is_notification = "id" not in reqif req.get("jsonrpc") != "2.0" or "method" not in req:return None if is_notification else error(-32600, "Invalid Request", _id)method = req["method"]fn = methods.get(method)if not fn:return None if is_notification else error(-32601, "Method not found", _id)params = req.get("params", [])try:if isinstance(params, list):result = fn(*params)elif isinstance(params, dict):result = fn(**params)else:return None if is_notification else error(-32602, "Invalid params", _id)return None if is_notification else success(result, _id)except TypeError as te:return None if is_notification else error(-32602, "Invalid params", _id, str(te))except Exception as ex:return None if is_notification else error(-32603, "Internal error", _id, str(ex))@app.post("/rpc")
async def rpc_entry(request: Request):try:payload = await request.json()except Exception:# 解析失败:id 必须为 nullreturn JSONResponse(error(-32700, "Parse error", None), status_code=200)# 批量if isinstance(payload, list):responses = []for item in payload:if not isinstance(item, dict):responses.append(error(-32600, "Invalid Request", None))continuer = handle_one(item)if r is not None:responses.append(r)# 纯通知批:不返回 body(204)if not responses:return Response(status_code=204)return JSONResponse(responses, status_code=200)# 单个if not isinstance(payload, dict):return JSONResponse(error(-32600, "Invalid Request", None), status_code=200)r = handle_one(payload)if r is None:  # 通知return Response(status_code=204)return JSONResponse(r, status_code=200)

调用示例(客户端)

import httpxresp = httpx.post("http://localhost:8000/rpc", json={"jsonrpc":"2.0","method":"sum","params":{"numbers":[1,2,3]},"id":"42"
})
print(resp.json())  # -> {"jsonrpc":"2.0","result":6,"id":"42"}

批量:一个请求 + 一个通知

batch = [{"jsonrpc":"2.0","method":"echo","params":{"msg":"Hi"},"id":1},{"jsonrpc":"2.0","method":"echo","params":{"msg":"No reply"}}   # 通知
]
print(httpx.post("http://localhost:8000/rpc", json=batch).json())

说明:JSON-RPC 对 HTTP 状态码不做规定。上面示例把应用层错误都塞在 200 的响应体里;纯通知返回 204。

最佳实践清单
• 鉴权:用 HTTP 头(如 Authorization: Bearer )或在传输层做认证(mTLS/WebSocket 子协议)。不要把密钥放进 params。
• 类型与校验:为方法参数建 Pydantic 模型;服务端在进入方法前先校验,定位错误更清晰。
• 日志与追踪:记录 method 与 id;链路里加超时与重试(注意幂等)。
• 批量与通知:通知无响应,适合非关键且幂等的操作(如埋点)。批量要考虑部分成功。
• ID 生成:客户端生成可追踪的字符串 ID(UUID/雪花);不要用自增数字以免冲突。
• 传输选择:
• HTTP:简单、易部署。
• WebSocket:天然双向,适合实时推送/订阅。
• stdio/管道:本地进程间协议(很多“工具/智能体”生态走这条)。

现成库(按语言)
• Python:fastapi-jsonrpc、jsonrpcserver、msgspec(自实现时做编解码)
• Node.js:jayson、json-rpc-2.0
• Go:github.com/sourcegraph/jsonrpc2
• Rust:jsonrpsee
• Java:jsonrpc4j

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/94391.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/94391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于CentOS7:Linux服务器的初始化流程

文章目录前言一、服务器初始化1.1 配置国内 Yum 源(加速软件安装)1.1.1 使用阿里云源1.1.2 使用清华源(可选)1.2 更新系统与安装必备工具1.3 网络连接验证1.4 配置主机名1.5 同步时间1.6 配置iptables防火墙1.6.1 手动配置iptable…

如何避免MyBatis二级缓存中的脏读

避免 MyBatis 二级缓存中的脏读问题(即缓存数据与数据库实际数据不一致),需要从缓存更新机制、配置策略、业务设计等多维度入手。以下是经过实践验证的解决方案,结合底层原理和具体实现:一、理解二级缓存脏读的根源脏读…

Python实现RANSAC进行点云直线、平面、曲面、圆、球体和圆柱拟合

本节我们分享使用RANSAC算法进行点云的拟合。RANSAC算法是什么?不知道的同学们前排罚站!(前面有)总的来说,RANSAC(Random Sample Consensus)是一种通用的迭代鲁棒估计框架,无论拟合何种几何模型&#xff0c…

实验2 天气预报

实验1 天气预报一、实验目标二、实验步骤(一)准备工作(二)小程序开发项目创建页面配置视图设计逻辑实现三、程序运行结果四、问题总结与体会主要问题及解决方案主要收获chunk的博客地址一、实验目标 1、掌握服务器域名配置和临时…

【CVE-2025-5419】(内附EXP) Google Chrome 越界读写漏洞【内附EXP】

前言 近日,奇安信CERT监测到Google Chrome中曝出一枚高危安全漏洞(CVE-2025-5419,QVD-2025-21836),该漏洞属于越界读写问题,攻击者只需通过构造恶意网页,就可能触发漏洞,从而绕过Chrome的沙箱防护,直接实现远程代码执行,最终完全控制用户设备。目前,安全社区已确认…

【科研绘图系列】R语言在海洋生态学中的应用:浮游植物糖类组成与溶解性有机碳的关系

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍 数据准备 数据处理 糖类组成随年龄的变化 糖类组成与DOC含量的关系 数据可视化 加载R包 数据下载 导入数据 数据预处理 画图 总结 系统信息 介绍 本教材通过R语言及其强大的数据…

webpack文件指纹:hash、chunkhash与contenthash详解

文件指纹就是打包后输出文件的后缀,每次构建都会生成不同的文件后缀,这样可以防止浏览器的默认缓存,使客户端代码可以及时修改。文件指纹的三种方式:‌ hash ‌:基于整个项目构建内容生成全局哈希值,任何文…

Pytest 插件怎么写:从0开发一个你自己的插件

概述 你用过 pytest-html 生成报告,或用 pytest-xdist 并行运行测试吗?这些强大的功能,其实都是 Pytest 插件 这些都是我们引入项目后直接使用的,当然 你也可以自己写一个 Pytest 插件 基本原理 Pytest 的强大,源于它的 插件系统。它允许你通过定义特定的函数(称为 H…

Java:IO流——基础篇

目录 前言 一、File 类 1、概述 ①构造方法 ②实例对象 2、使用 ①查看名称、路径、长度 ②判断、创建和删除操作 ③目录遍历操作 二、IO流 1、流的概念 2、流的分类 ①按数据流向 ②按数据类型 ③按功能 3、字节流 ⑴FileInputStream——文件输入流 ⑵FileOutputStream——文件…

数据挖掘 5.1~5.2 PCA——前言

5.1 Twelve ways to fool the masses 5.1 愚弄大众的十二种方法 5.2.1 Prelim: Old MacDonald meets Lagrange 5.2.1 前言:老麦克唐纳遇见拉格朗日 5.2. Prelim: Meet stubborn vectors 5.2. 前言:遇见顽固向量 5.2.3 Prelim: Covariance and its friend…

DeepSeek分析

(非走向数字时代,融入数字生活,构建数字生态的分解,只是感觉可以分享给大家---因此现设置VIP,旺海涵) 这是deepseek刚爆的时候,春节紧急对其做的分析。 内容还是私藏状态,做了初步评估,感觉可以分享给大家!!! 但是非共享的构建数字生态的核心,因此添加了vip设置…

2025第五届人工智能、自动化与高性能计算国际会议 (AIAHPC 2025)

重要信息 官网:www.aiahpc.org 时间:2025年9月19-21日 地点:中国合肥 主题 1、高性能计算 并行和分布式系统架构 高性能计算的语言和编译器 并行和分布式软件技术 并行和分布式算法 嵌入式系统 计算智能 点对点计算 网格和集群计算…

CORS解决跨域问题的多个方案 - nginx站点配置 / thinkphp框架内置中间件 / 纯前端vue、vite的server.proxy代理

效果图 跨域报错 跨域解决 方案实测 1. nginx、apache站点配置 > OK 2. thinkphp框架内置中间件 “跨域请求支持” > OK 3. 纯前端vue、vite的server.proxy代理 > 不OK 方案具体设置 1. nginx、apache站点配置 > OK 修改nginx服务器的站点的跨域信息 日志下…

什么是Omni-Hub?一套面向“万物智联”时代的操作系统级方法论

Omni-Hub(中文常译“全向中枢”),是一套面向未来数字化生态的开放型系统级框架,由“Omni”(全域、全向、全模态)与“Hub”(中枢、枢纽)组合而成,旨在通过统一接口、协议与…

ARP地址解析协议

工作原理ARP是一个封装于数据链路层的二层协议,其目的主要是将IP地址解析为MAC地址,通过广播🔉询问Who is x.x.x.x,对方收到后单播回应自己的mac地址动态ARP动态ARP通过ARP协议自动学习和维护IP与MAC的映射关系,表项具…

PortSwigger靶场之Blind SQL injection with out-of-band interaction通关秘籍

一、题目分析 该实验室存在一个盲 SQL 注入漏洞。该应用程序使用跟踪 cookie 进行分析,并执行包含所提交 cookie 值的 SQL 查询。该 SQL 查询是异步执行的,不会对应用程序的响应产生影响。不过,我们可以与外部域触发非带内交互。要解决此漏洞…

笔试-笔记3

1.在以下声明中哪一个表示“指向常量的指针”(指针指向的内容不能修改)? A.char* const p B.const char* p C.char *p const D.char const p 解析: 选B,const修饰的变量为常量,意味着不能修改 A是常量指针,const修饰的…

Linux正则表达式

文章目录一、Linux正则表达式与三剑客知识1.什么是正则表达式?2.为什么要学习正则表达式?3.有关正则表达式容易混淆的事项4.学习正则表达式注意事项5. 正则表达式的分类5.1 基本的正则表达式(BRE)集合6. 正则表达式测试题7. 扩展正…

MATLAB Figure画布中绘制表格详解

文章目录 1 使用uitable创建带有样式和颜色映射的表格 2 使用imagesc和text创建自定义表格 3 使用patch和text创建完全自定义的表格 4 代码详细讲解 4.1 使用uitable 4.2 使用imagesc和text 4.3 使用patch和text 5 颜色映射技巧 5.1 使用内置颜色映射 5.2 自定义颜色映射函数 5…

Python在语料库建设中的应用:文本收集、数据清理与文件名管理

一、问题的提出在日常语言学习与教学中,语料库是一个不可或缺的工具。它可以帮助我们查找高频词,获取搭配信息、例句信息、关键词信息等。由于建库过程操作步骤多,有时还要用到图片识别、格式转化、文本清理等技巧,很多人往往都止…