吐血整理JSON-RPC2.0的原理与应用
吐血整理JSON-RPC2.0的原理与应用作为一名全栈工程师我在日常开发中经常需要处理不同服务之间的远程调用问题。从RESTful API到gRPC再到WebSocket每种协议都有自己的适用场景。但有一个协议它轻量、跨语言、且天然支持异步调用那就是JSON-RPC。今天我就从原理到实战彻底讲清楚JSON-RPC 2.0。## 什么是JSON-RPC 2.0JSON-RPC是一种无状态的、轻量级的远程过程调用RPC协议。它使用JSON作为数据格式基于HTTP或TCP等传输层协议工作。JSON-RPC 2.0是目前最广泛使用的版本规范简单清晰非常适合微服务间通信、浏览器扩展、区块链应用如以太坊等场景。核心特性-无状态每次调用都是独立的不依赖上下文-轻量级JSON编码易于解析和生成-支持批量调用一次请求可以发送多个调用-通知机制无需响应的单向消息## 协议规范详解JSON-RPC 2.0的请求对象包含以下字段-jsonrpc必须为2.0-method要调用的方法名字符串-params参数可选可以是数组或对象-id请求标识符可用于匹配响应通知时可为null响应对象包含-jsonrpc必须为2.0-result成功时的返回值成功时必需-error失败时的错误对象失败时必需-id与请求相同的id错误对象包含-code错误码整数-message错误描述字符串-data附加数据可选标准错误码--32700解析错误--32600无效请求--32601方法不存在--32602无效参数--32603内部错误--32000~-32099服务器错误## 实战Python实现一个简单的JSON-RPC服务器下面我用Python从零搭建一个JSON-RPC服务器支持基本调用和错误处理。### 示例1基础JSON-RPC服务器python# json_rpc_server.pyimport jsonfrom http.server import HTTPServer, BaseHTTPRequestHandlerclass JSONRPCHandler(BaseHTTPRequestHandler): # 定义可用方法 methods { add: lambda a, b: a b, subtract: lambda a, b: a - b, echo: lambda msg: msg, divide: lambda a, b: a / b # 注意可能除零错误 } def do_POST(self): # 读取请求体 content_length int(self.headers[Content-Length]) body self.rfile.read(content_length).decode(utf-8) try: request json.loads(body) except json.JSONDecodeError as e: # 处理JSON解析错误 self.send_response(200) self.send_header(Content-Type, application/json) self.end_headers() error_response { jsonrpc: 2.0, error: { code: -32700, message: Parse error, data: str(e) }, id: None } self.wfile.write(json.dumps(error_response).encode()) return # 验证jsonrpc版本 if request.get(jsonrpc) ! 2.0: self.send_response(200) self.send_header(Content-Type, application/json) self.end_headers() error_response { jsonrpc: 2.0, error: {code: -32600, message: Invalid Request}, id: request.get(id, None) } self.wfile.write(json.dumps(error_response).encode()) return method_name request.get(method) params request.get(params, []) request_id request.get(id) # 检查方法是否存在 if method_name not in self.methods: response { jsonrpc: 2.0, error: {code: -32601, message: fMethod {method_name} not found}, id: request_id } else: try: # 调用方法 if isinstance(params, list): result self.methods[method_name](*params) elif isinstance(params, dict): result self.methods[method_name](**params) else: result self.methods[method_name]() response { jsonrpc: 2.0, result: result, id: request_id } except Exception as e: # 捕获运行时错误 response { jsonrpc: 2.0, error: {code: -32603, message: Internal error, data: str(e)}, id: request_id } self.send_response(200) self.send_header(Content-Type, application/json) self.end_headers() self.wfile.write(json.dumps(response).encode())if __name__ __main__: server HTTPServer((localhost, 8080), JSONRPCHandler) print(JSON-RPC server running on http://localhost:8080) server.serve_forever()测试命令使用curlbash# 正常调用curl -X POST http://localhost:8080 -H Content-Type: application/json -d {jsonrpc:2.0,method:add,params:[3,5],id:1}# 错误调用方法不存在curl -X POST http://localhost:8080 -H Content-Type: application/json -d {jsonrpc:2.0,method:unknown,params:[],id:2}### 示例2支持批量调用的客户端python# json_rpc_client.pyimport jsonimport requestsclass JSONRPCClient: def __init__(self, endpoint): self.endpoint endpoint def call(self, method, paramsNone, request_id1): 单个RPC调用 :param method: 方法名 :param params: 参数列表或字典 :param request_id: 请求ID :return: 响应结果 payload { jsonrpc: 2.0, method: method, id: request_id } if params is not None: payload[params] params response requests.post(self.endpoint, jsonpayload) response_data response.json() if error in response_data: raise Exception(fRPC Error: {response_data[error]}) return response_data.get(result) def batch_call(self, calls): 批量RPC调用 :param calls: 列表每个元素是(method, params, request_id)元组 :return: 响应列表 batch_payload [] for method, params, request_id in calls: payload { jsonrpc: 2.0, method: method, id: request_id } if params is not None: payload[params] params batch_payload.append(payload) response requests.post(self.endpoint, jsonbatch_payload) response_data response.json() # 返回结果映射按id排序 results {} for item in response_data: if result in item: results[item[id]] item[result] elif error in item: results[item[id]] {error: item[error]} return results def notify(self, method, paramsNone): 发送通知无需响应 :param method: 方法名 :param params: 参数 payload { jsonrpc: 2.0, method: method, params: params } # 通知没有id字段 requests.post(self.endpoint, jsonpayload)# 使用示例if __name__ __main__: client JSONRPCClient(http://localhost:8080) # 单个调用 result client.call(add, [10, 20], 1) print(fadd(10,20) {result}) # 输出: 30 # 使用命名参数 result client.call(subtract, {a: 10, b: 3}, 2) print(fsubtract(10,3) {result}) # 输出: 7 # 批量调用 batch_calls [ (add, [1, 2], 10), (echo, [hello world], 11), (divide, [10, 2], 12), (divide, [10, 0], 13) # 这个会出错 ] results client.batch_call(batch_calls) print(fBatch results: {results}) # 输出: {10: 3, 11: hello world, 12: 5.0, 13: {error: {...}}} # 发送通知 client.notify(echo, [this is a notification])## 高级应用与WebSocket集成在需要实时通信的场景如聊天应用、实时数据推送JSON-RPC与WebSocket结合非常强大。下面是一个基于WebSocket的JSON-RPC实现片段python# websocket_rpc_server.py使用websockets库import asyncioimport jsonimport websocketsclass WebSocketRPCServer: def __init__(self): self.methods { ping: lambda: pong, get_time: lambda: asyncio.get_event_loop().time() } async def handle_message(self, websocket, message): try: request json.loads(message) except json.JSONDecodeError: await websocket.send(json.dumps({ jsonrpc: 2.0, error: {code: -32700, message: Parse error}, id: None })) return method request.get(method) params request.get(params, []) request_id request.get(id) if method in self.methods: try: result self.methods[method](*params) if isinstance(params, list) else self.methods[method](**params) response { jsonrpc: 2.0, result: result, id: request_id } except Exception as e: response { jsonrpc: 2.0, error: {code: -32603, message: str(e)}, id: request_id } else: response { jsonrpc: 2.0, error: {code: -32601, message: Method not found}, id: request_id } await websocket.send(json.dumps(response)) async def handler(self, websocket, path): async for message in websocket: await self.handle_message(websocket, message)# 启动服务器# start_server websockets.serve(WebSocketRPCServer().handler, localhost, 8765)# asyncio.get_event_loop().run_until_complete(start_server)# asyncio.get_event_loop().run_forever()## 应用场景总结JSON-RPC 2.0在实际项目中应用广泛1.微服务通信在Kubernetes集群中服务间调用可以使用JSON-RPC比REST更直接2.区块链以太坊的JSON-RPC接口是开发者与智能合约交互的标准方式3.浏览器扩展Chrome扩展的消息传递机制类似JSON-RPC4.IoT设备轻量级协议适合资源受限设备## 总结JSON-RPC 2.0是一个被低估的协议它的简洁性使其成为很多场景的理想选择。通过本文的代码示例你可以看到- 实现一个JSON-RPC服务器只需要不到100行Python代码- 批量调用可以大幅提升性能减少HTTP连接数- 通知机制适用于日志、监控等单向消息场景- 与WebSocket结合可以实现双向实时通信在实际项目中我建议- 对于内部服务调用优先考虑JSON-RPC而非REST减少HTTP开销- 使用标准的错误码便于客户端统一处理- 注意安全性总是验证请求的jsonrpc字段和参数类型- 考虑使用成熟库如Python的jsonrpcserver、jsonrpcclient减少重复造轮子希望这篇文章能帮你彻底掌握JSON-RPC 2.0并在你的下一个项目中高效使用它。

相关新闻

MCSPI控制器模式详解:从信号定义到实战配置的嵌入式SPI开发指南

MCSPI控制器模式详解:从信号定义到实战配置的嵌入式SPI开发指南

1. MCSPI控制器模式:从信号定义到实战配置的深度解析在嵌入式系统开发中,SPI(Serial Peripheral Interface)几乎是工程师的“必修课”。它简单、高效,是连接传感器、存储器、显示屏等外设的“血管”。但当你从标准SPI转…

2026/7/25 16:52:03 阅读更多 →
TI C2000 MibSPI寄存器深度解析:从引脚控制到数据传输实战

TI C2000 MibSPI寄存器深度解析:从引脚控制到数据传输实战

1. 项目概述与核心价值在嵌入式开发,尤其是基于德州仪器(TI)C2000、Hercules等系列MCU的项目中,SPI(串行外设接口)是连接Flash、传感器、ADC/DAC等外设的“血管”。但很多开发者,尤其是刚接触TI…

2026/7/25 16:52:03 阅读更多 →
ZeroOmega:终极浏览器代理管理解决方案,轻松掌控网络访问

ZeroOmega:终极浏览器代理管理解决方案,轻松掌控网络访问

ZeroOmega:终极浏览器代理管理解决方案,轻松掌控网络访问 【免费下载链接】ZeroOmega Manage and switch between multiple proxies quickly & easily. 项目地址: https://gitcode.com/gh_mirrors/ze/ZeroOmega ZeroOmega是一款强大的开源浏览…

2026/7/25 16:52:03 阅读更多 →

最新新闻

基于MediaPipe Holistic与Unity的实时人体姿态驱动实战指南

基于MediaPipe Holistic与Unity的实时人体姿态驱动实战指南

1. 项目概述:从“动捕棚”到“单摄像头”的实时姿态革命如果你做过角色动画,肯定知道传统动捕(Motion Capture)有多麻烦。要么得租用昂贵的动捕棚,让演员穿上布满反光球的紧身衣,在几十个红外摄像头下表演&…

2026/7/25 17:06:11 阅读更多 →
HEIF Utility:Windows上必备的免费HEIF图片转换器终极解决方案

HEIF Utility:Windows上必备的免费HEIF图片转换器终极解决方案

HEIF Utility:Windows上必备的免费HEIF图片转换器终极解决方案 【免费下载链接】HEIF-Utility HEIF Utility - View/Convert Apple HEIF images on Windows. 项目地址: https://gitcode.com/gh_mirrors/he/HEIF-Utility 还在为iPhone拍摄的照片在Windows电脑…

2026/7/25 17:06:11 阅读更多 →
OpenClaw AI:私有化部署智能对话系统实战指南

OpenClaw AI:私有化部署智能对话系统实战指南

1. 项目概述:打造全天候AI私人助理 去年我在家里部署了一套智能问答系统,现在每天起床第一件事就是问它天气、新闻和日程安排。这种7x24小时在线的AI助手彻底改变了我的工作效率和生活习惯。今天要分享的OpenClaw AI搭建方案,正是基于我半年来…

2026/7/25 17:06:11 阅读更多 →
Kali Linux系统服务与进程管理:渗透测试环境控制与安全洞察实战

Kali Linux系统服务与进程管理:渗透测试环境控制与安全洞察实战

1. 项目概述:为什么渗透测试者必须关注系统服务与进程? 如果你刚开始接触Kali Linux,可能觉得它就是个“黑客工具箱”,装满了各种炫酷的扫描、漏洞利用工具。但真正想用它干点实事,比如做一次完整的渗透测试&#xff0…

2026/7/25 17:06:11 阅读更多 →
告别DLL地狱!一次性搞定所有Visual C++运行库的终极解决方案

告别DLL地狱!一次性搞定所有Visual C++运行库的终极解决方案

告别DLL地狱!一次性搞定所有Visual C运行库的终极解决方案 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 还在为"缺少MSVCP140.dll"、&qu…

2026/7/25 17:06:11 阅读更多 →
League-Toolkit:英雄联盟玩家的智能效率助手

League-Toolkit:英雄联盟玩家的智能效率助手

League-Toolkit:英雄联盟玩家的智能效率助手 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 还在为英雄联盟中繁琐的符文配置、英雄…

2026/7/25 17:05:10 阅读更多 →

日新闻

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解决您的…

2026/7/25 0:00:35 阅读更多 →
C++ string类模拟实现:从深拷贝到内存管理的完整指南

C++ string类模拟实现:从深拷贝到内存管理的完整指南

1. 项目概述:为什么我们要“手撕”string类?在C的学习道路上,尤其是从C语言过渡到C的“初阶”阶段,string类绝对是一个绕不开的核心。标准库里的std::string用起来太方便了,、find、substr,几个操作符和函数…

2026/7/25 0:00:35 阅读更多 →
三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

1. 先搞清楚“三角洲寻宝鼠”到底是什么工具从名称来看,“三角洲寻宝鼠”更像是一个资源查找或文件检索类工具,而不是游戏或娱乐软件。这类工具的核心价值在于帮助用户快速定位特定资源,比如文档、图片、压缩包或特定格式的文件。如果你经常需…

2026/7/25 0:00:35 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/25 5:08:22 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/25 5:13:53 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 18:52:18 阅读更多 →

月新闻