Python-JsonRPC
Python-JsonRPC
使用Python学习JsonRPC数据交互
1-核心知识点
- 1)什么是JsonRPC,这种协议是如何工作的?->使用请求进行验证
- 2)JsonRPC可以使用Postman进行验证吗?->可以使用POSTMAN进行调用(使用HTTP请求即可)
- 3)gRPC和jsonRPC对比->jsonRPC更早也更轻量级但是性能不高
2-思路整理
- 1)JsonRPC也可以编写服务器进行约定参数传递
- 2)但是JsonRPC性能不高
3-参考网址
- Postman 快速调用 JSON-RPC 接口
- 个人实现代码仓库:https://gitee.com/enzoism/python_json_rpc
4-动手实践
1-初始化环境
mkdir my_project
cd my_project
python -m venv .venv
2-激活环境
# Windows
source .venv/Scripts/activate# Mac
source .venv/bin/activate
3-添加依赖
对应的依赖是在激活的环境中
pip install flask requests
4-创建JsonRPC服务端
from flask import Flask, request, jsonify
import jsonapp = Flask(__name__)# 注册支持的 RPC 方法到字典
rpc_methods = {}def register_rpc(method_name):"""装饰器:注册一个 RPC 方法"""def decorator(func):rpc_methods[method_name] = funcreturn funcreturn decorator@app.route('/rpc', methods=['POST'])
def rpc_handler():"""处理 JSON-RPC 请求"""data = request.get_json()# 验证请求格式if not data or data.get('jsonrpc') != '2.0':return jsonify({'jsonrpc': '2.0','id': None,'error': {'code': -32600,'message': 'Invalid Request'}}), 400method = data.get('method')params = data.get('params', [])_id = data.get('id')# 调用对应方法if method in rpc_methods:try:# 根据参数类型确定调用方式:数组参数 vs 对象参数if isinstance(params, list):result = rpc_methods[method](*params)elif isinstance(params, dict):result = rpc_methods[method](**params)else:raise TypeError("Parameters must be list or object")return jsonify({'jsonrpc': '2.0','id': _id,'result': result})except Exception as e:return jsonify({'jsonrpc': '2.0','id': _id,'error': {'code': -32603,'message': 'Internal error','data': str(e)}}), 500else:return jsonify({'jsonrpc': '2.0','id': _id,'error': {'code': -32601,'message': 'Method not found'}}), 404# 注册示例 RPC 方法@register_rpc('add')
def add(a: int, b: int):"""两个数相加"""return a + b@register_rpc('subtract')
def subtract(minuend: int, subtrahend: int):"""两个数相减"""return minuend - subtrahahend # 故意写错拼写,演示错误处理if __name__ == '__main__':app.run(port=5000)
5-验证JsonRPC服务
当前直接运行Python验证脚本
python test_rpc.py# 1-测试加法->成功请求,返回3
Test 'add': {'id': 1, 'jsonrpc': '2.0', 'result': 3}# 2-测试乘法->(因为没有定义)失败请求,返回Method not found
Test 'multiply': {'error': {'code': -32601, 'message': 'Method not found'}, 'id': 1, 'jsonrpc': '2.0'}# 3-测试减法->(因为语法错误)失败请求,返回subtrahahend is not defined
Test 'subtract': {'error': {'code': -32603, 'data': "name 'subtrahahend' is not defined", 'message': 'Internal error'}, 'id': 1, 'jsonrpc': '2.0'}
- 服务器接收请求参数
- 执行验证脚本
6-Postman验证
- POST请求数据
5-核心逻辑
1-主要代码解析
1-服务端核心逻辑
-
可用方法注册:
- 通过装饰器
@register_rpc('method_name')
将函数注册为可用的 RPC 方法。
- 通过装饰器
-
请求处理:
- 检查必需字段(
jsonrpc
、method
、id
)。 - 根据参数类型(列表或字典)分别解析参数:
if isinstance(params, list):result = method(*params) elif isinstance(params, dict):result = method(**params)
- 检查必需字段(
-
错误处理:
- 内部错误返回
code=-32603
- 方法未找到返回
code=-32601
- 不符合请求格式时返回
code=-32600
- 内部错误返回
2-客户端核心逻辑
- 构造标准的 JSON-RPC 请求对象
- 发送 POST 请求并接收响应
- 根据返回的
id
和结果/错误信息进行处理
2-扩展说明
-
更复杂的错误处理:
服务端可以在错误对象中添加更多信息(如data
字段):"error": {"code": -32000,"message": "Division by zero","data": "Denominator is zero" }
-
支持变量请求ID:
可以让id
动态生成:import uuid payload['id'] = str(uuid.uuid4())
-
支持批量请求:
服务端可以处理包含多个 RPC 请求的数组,客户端修改请求格式:payloads = [{"jsonrpc": "2.0", "method": "add", "params": [1,2], "id": 1},{"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 5, "subtrahend":3 }, "id": 2} ]response = requests.post(f"{base_url}/rpc", json=payloads)
3-使用场景说明
- 为什么选择 Flask?
- 易于搭建简单服务(3分钟内可启动服务端)
- 适合快速开发原型系统
- 支持 HTTP/HTTPS,默认兼容 JSON 格式
- 为什么选择 requests?
- Python 标准库函数支持构建 JSON 请求
- 轻量级,不需要额外配置即可发送 HTTP 请求
4-其他实现方式
如果需要一个更完整的 JSON-RPC 库,可以使用:
- jsonrpclib(Python2和Python3都支持,基于HTTP的简单库)
- aiohttp_json_rpc(支持异步的 Python3 高级库)
6-补充说明
gRPC 和 JSON-RPC 都是远程过程调用(RPC)框架,用于服务之间的通信,但在通信协议、性能、序列化方式等方面存在显著差异。以下是两者的对比分析:
1. 基本概念
gRPC
- 定义:由 Google 开发的高性能、开源、通用 RPC 框架,基于 Protocol Buffers(一种二进制序列化协议)和 HTTP/2 协议。
- 设计目标:提供高性能、低延迟的通信,适用于分布式系统和微服务架构。
- 特性:
- 支持 HTTP/2(支持双向流、多路复用、服务器推送)。
- 支持多种语言(如 Java、Python、Go、C++ 等)。
- 原生支持流式(流-流、流-单、单-流)通信。
- 需通过
.proto
文件定义接口(接口描述语言,IDL)。
JSON-RPC
- 定义:基于 JSON 的轻量级 RPC 协议,最早在 2005 年提出。
- 设计目标:提供简单、灵活的远程调用,通常用于 Web 应用或轻量级服务间通信。
- 特性:
- 通常基于 HTTP/1.1 或 TCP 传输层。
- 使用 JSON 格式序列化数据(文本格式,可读性强)。
- 支持同步和异步调用(具体实现依赖客户端/服务器)。
- 无接口定义语言(IDL),接口需通过契约或文档约定。
2. 核心差异对比
特性 | gRPC | JSON-RPC |
---|---|---|
协议基础 | HTTP/2 + Protocol Buffers | HTTP/1.1 或 TCP + JSON |
序列化格式 | Binary(Protocol Buffers) → 效率高 | JSON(文本格式) → 可读性好,但较冗余 |
性能与效率 | 高性能(二进制、HTTP/2、流式支持) | 较低(文本 JSON 的解析开销和 HTTP/1.1 的头部开销) |
语言支持 | 官方支持多种语言(Java、Go、Python等) | 主流语言均有实现,依赖社区支持 |
流式通信 | 双向流(客户端-服务端双向实时通信) | 基本不支持(需借助 WebSocket 等扩展) |
接口定义(IDL) | 需通过 .proto 文件定义接口 | 无正统 IDL,需通过文档或 JSON Schema 约定 |
传输层特性 | HTTP/2(多路复用、二进制帧) | HTTP/1.1(文本请求头、每请求一次连接) |
错误处理 | 基于 Status 对象和 HTTP 状态码 | 遵循 JSON-RPC 标准的错误对象格式 |
部署复杂度 | 略高(需配置 HTTP/2,且依赖 Protocol Buffers 编译工具链) | 较低(无需额外依赖,JSON 生态成熟) |
适用场景 | 高内聚微服务(例如:需要低延迟的内部通信) | 轻量级服务、Web 应用、前端与后端通信(REST 风格) |
3. 典型使用场景
gRPC 适用场景
- 高性能需求:微服务内部通信、需要低延迟和高吞吐量的场景。
- 语言异构性:跨语言服务调用(如 Java 后端调用 Go 的服务)。
- 流式数据处理:实时数据传输(如 IoT 设备数据推送、实时日志监控)。
- 需要强类型安全:通过 Protocol Buffers 的
.proto
文件定义接口,确保接口强一致性。
JSON-RPC 适用场景
- 简单服务间通信:轻量级服务间交互,无需复杂性能优化。
- Web 前端集成:前端通过 HTTP 与后端直接通信(如通过浏览器调用后端 API)。
- 快速原型开发:无需编译步骤,直接通过 JSON 构造请求,适合敏捷开发场景。
- 遗留系统兼容性:老旧系统中已有 JSON 处理能力,无需引入新的协议栈。
4. 优缺点总结
gRPC 的优点
- 性能高效:二进制格式减少网络开销,HTTP/2 的多路复用提升连接效率。
- 强类型支持:通过
.proto
文件定义接口,代码生成工具自动处理序列化/反序列化。 - 双向流:支持实时性强的双向通信场景。
- 安全集成:内置对 TLS 和 JWT 的支持,且有成熟的插件生态(如 gRPC-gateway 可生成 REST API)。
gRPC 的缺点
- 复杂度较高:依赖 Protocol Buffers 的编译工具链,学习曲线较陡。
- 客户端浏览器支持有限:大多数浏览器未直接支持 HTTP/2 的流式交互,需通过代理或 gRPC-Web 方案。
- 调试较麻烦:二进制格式不利于直接查看流量内容。
JSON-RPC 的优点
- 轻量易用:无依赖,基于通用的 HTTP/JSON,开发简单。
- 可读性强:JSON 格式便于调试和人眼阅读。
- 浏览器友好:天然支持标准 HTTP/1.1,可直接通过 JavaScript 调用。
JSON-RPC 的缺点
- 性能较低:JSON 的文本格式导致序列化/反序列化开销大,且 HTTP/1.1 头部冗余。
- 无接口强约束:易出现接口一致性问题,依赖文档维护。
- 无流式支持:单向请求-响应模型,不适合实时交互。
5. 如何选择?
-
选 gRPC:
- 内部微服务通信需高性能、低延迟。
- 跨语言且需要强类型接口定义。
- 需要流式实时通信(如实时数据推送)。
- 接口稳定性要求高(通过编译时检查避免类型不一致)。
-
选 JSON-RPC:
- 场景简单且对性能要求不苛刻。
- 需要与 Web 前端直接交互(如通过浏览器向后端发起请求)。
- 快速实现或 MVP(最小可行产品)阶段。
- 服务间协议必须保持高度灵活性(如需动态扩展字段)。
6. 补充说明
- JSON-over-gRPC:可通过
google.protobuf.Struct
或JSONPB
在 gRPC 消息中嵌入 JSON 数据,兼顾二进制效率和灵活性。 - gRPC-Web:通过代理(如
Envoy
或自建网关)将 gRPC 的 HTTP/2 协议转换为 HTTP/1.1,适用于浏览器支持。 - JSON-RPC 3:标准化的 JSON-RPC 3.0 提供了更灵活的扩展机制,但实际应用中仍以 2.0 协议为主。
相关文章:

Python-JsonRPC
Python-JsonRPC 使用Python学习JsonRPC数据交互 1-核心知识点 1)什么是JsonRPC,这种协议是如何工作的?->使用请求进行验证2)JsonRPC可以使用Postman进行验证吗?->可以使用POSTMAN进行调用(使用HTTP请…...

Redis从入门到实战——实战篇(下)
四、达人探店 1. 发布探店笔记 探店笔记类似于点评网站的评价,往往是图文结合。对应的表有两个: tb_blog:探店笔记表,包含笔记中的标题、文字、图片等tb_blog_comments:其他用户对探店笔记的评价 步骤①࿱…...

面试问题(连载。。。。)
flexbox 和 crid 的区别 1. 布局维度与核心特性 Flexbox(弹性盒子) 一维布局:专注于行或列的线性排列,适合单方向(水平或垂直)的布局需求。动态分配空间:通过 flex-grow、flex-shrink 和 flex…...
springboot项目tomcat中加载不了
Spring Boot项目在Tomcat中加载不了的问题可能由多种原因引起,包括打包方式不正确、依赖配置错误、启动类配置不当等。以下是详细的解决方案: 1. 修改项目打包形式 将项目打包形式从jar改为war,以确保项目以正确的格式被Tomcat加载。在pom.…...
venv和pyenv在mac上
是的,理论上你可以用 venv 选择 Python 版本,但有一个关键前提:系统中必须已安装该版本的 Python 解释器。venv 本身并不提供 Python 版本管理功能,它只是基于现有的 Python 环境创建虚拟隔离空间。以下分场景详细说明:…...

OpenCv实战笔记(1)在win11搭建opencv4.11.1 + qt5.15.2 + vs2019_x64开发环境
一. 准备工作 Visual Studio 2019(安装时勾选 C 桌面开发 和 Windows 10 SDK) CMake 3.20(官网下载) Qt 5.15.2(下载 Qt Online Installer)安装时勾选 MSVC 2019 64-bit 组件。 opencv 4.11.1 源码下载 git…...
前端获取流式数据并输出
在一些实时对话、日志推送等场景下,如果使用传统一次性加载数据的方式,可能会出现等待时间较长的不友好交互,这个时候我们需要使用流式布局分段获取数据,渐进式加载,减少等待焦虑。 原生js上,我们使用fetch…...

全局网络:重构数字时代的连接范式
从局部到全局 —— 网络架构的范式革命 在全球化与数字化深度融合的今天,传统网络架构的 “碎片化” 问题日益凸显:跨地域数据流通低效、设备互联孤岛化、安全策略难以统一。 全局网络作为一种突破地域与技术边界的新型网络架构,正成为企业…...

C++ Primer (第五版)-第十四章重载运算与类型转换
文章目录 一、基本概念可以被重载某些运算符不应被重载尽量明智使用运算符重载赋值和复合赋值运算符选择作为成员或者非成员 输入和输出运算符输入运算符尽量减少格式化操作输入输出运算符必须是非成员函数 重载输入运算符>>输入时的错误标示错误 算数和关系运算符相等运…...
nt!MiSessionAddProcess函数分析和nt!MmSessionSpace全局变量的关系
第一部分: 1: kd> g Breakpoint 42 hit nt!MiSessionAddProcess: 80ab2fbe 55 push ebp 1: kd> kc # 00 nt!MiSessionAddProcess 01 nt!MmCreateProcessAddressSpace 02 nt!PspCreateProcess 03 nt!NtCreateProcessEx 04 nt!_KiSystemServic…...

鸿蒙开发——5.ArkUI @Builder装饰器:打造高效可复用的UI组件
鸿蒙开发——5.ArkUI Builder装饰器:打造高效可复用的UI组件 ArkUI Builder装饰器:打造高效可复用的UI组件一、Builder装饰器是什么?二、两种构建函数类型1. 私有自定义构建函数2. 全局自定义构建函数 三、参数传递核心规则1. 按值传递&#…...
bash和zsh的区别
Bash(Bourne-Again SHell)和 Zsh(Z Shell)都是 Unix/Linux 系统中的主流 Shell,但它们在功能、配置和用户体验上有显著区别。以下是两者的详细对比: 1. 历史与兼容性 特性BashZsh诞生时间1989 年ÿ…...

PyTorchVideo实战:从零开始构建高效视频分类模型
视频理解作为机器学习的核心领域,为动作识别、视频摘要和监控等应用提供了技术基础。本教程将详细介绍如何利用PyTorchVideo和PyTorch Lightning两个强大框架,构建基于Kinetics数据集训练的3D ResNet模型,实现高效的视频分类流程。 PyTorch…...
深入理解Spring缓存注解:@Cacheable与@CacheEvict
在现代应用程序开发中,缓存是提升系统性能的重要手段。Spring框架提供了一套简洁而强大的缓存抽象,其中Cacheable和CacheEvict是两个最常用的注解。本文将深入探讨这两个注解的工作原理、使用场景以及最佳实践。 1. Cacheable注解 基本概念 Cacheable…...
Rust 与 Golang 深度对决:从语法到应用场景的全方位解析
一、引言 在软件开发的快速发展浪潮中,Rust 和 Golang(Go 语言)脱颖而出,成为开发者热议的编程语言。Rust 凭借强大的内存安全性与卓越的性能备受赞誉,Golang 则以简洁的语法和出色的并发处理能力赢得开发者青睐。本文…...
java加强 -泛型
概念 定义类、接口、方法时,同时声明了一个或多个类型变量(如<E>),称为泛型类、泛型接口、泛型方法、它们统称为泛型。 语法 public class ArrayList<E>{} E可以接收不同类型的数据,可以是字符串&…...
pygame联网飞机大战游戏实现
客户端 import pygame import socket import json import threadingclass GameClient:def __init__(self):pygame.init()self.screen_width 600 # 宽度减小self.screen_height 800 # 高度增加self.screen pygame.display.set_mode((self.screen_width, self.screen_heigh…...

SEMI E40-0200 STANDARD FOR PROCESSING MANAGEMENT(加工管理标准)-(二)
8 行为规范 8.1 本章定义监督实体(Supervisor)与加工资源(Processing Resource)为实现物料加工所需的高层级通信逻辑,不涉及具体消息细节(详见第10章消息服务)。 8.2 加工任务通信 8.2.1 加工…...

根据窗口大小自动调整页面缩放比例,并保持居中显示
vue 项目 直接上代码 图片u1.png 是个背景图片 图片u2.png 是个遮罩 <template><div id"app"><div class"viewBox"><divclass"screen":style"{ transform: translate(-50%,-50%…...
如何在Jmeter中调用C程序?
在JMeter中调用C语言程序可以通过以下几种方式实现: 方法一:使用OS Process Sampler JMeter的“OS Process Sampler”可以用来调用外部程序,包括C语言编写的可执行文件。 步骤: 准备C语言程序: 编写C语言代码并编译…...

Android SDK 国内镜像及配置方法(2025最新,包好使!)
2025最新android sdk下载配置 1、首先你需要有android sdk manager2、 直接上教程修改hosts文件配置域名映射即可(不用FQ)2.1 获取ping dl.google.com域名ip地址2.2 配置hosts文件域名映射2.3 可以随意下载你需要的sdk3、 总结:走过弯路,踩过坑!!!大家就不要踩了!避坑1…...

【Python开源】深度解析:一款高效音频封面批量删除工具的设计与实现
🎵 【Python开源】深度解析:一款高效音频封面批量删除工具的设计与实现 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代码,热情…...

OpenStack Yoga版安装笔记(26)实例元数据笔记
一、实例元数据概述 1.1 元数据 (官方文档:Metadata — nova 25.2.2.dev5 documentation) Nova 通过一种叫做元数据(metadata)的机制向其启动的实例提供配置信息。这些机制通常通过诸如 cloud-init 这样的初始化软件…...

【Linux】swap交换分区管理
目录 一、Swap 交换分区的功能 二、swap 交换分区的典型大小的设置 2.1 查看交换分区的大小 2.1.1 free 2.1.2 cat /proc/swaps 或 swapon -s 2.1.3 top 三、使用交换分区的整体流程 3.1 案例一 3.2 案例二 一、Swap 交换分区的功能 计算机运行一个程序首先会将外存&am…...
Spring IoC (Inversion of Control) 控制反转是什么?
我们分析一下 IoC (Inversion of Control) 控制反转的核心思想。 核心思想: IoC 是一种设计原则(Design Principle),它描述了一种软件设计模式,其中组件(对象)的创建、依赖关系的管理和生命周…...
互联网大厂Java求职面试:核心技术点深度解析
互联网大厂Java求职面试:核心技术点深度解析 在互联网大厂的Java岗位面试中,技术总监级别的面试官通常会从实际业务场景出发,层层深入地考察候选人的技术能力。本文通过一个严肃专业的技术总监与搞笑但有技术潜力的程序员郑薪苦之间的互动对…...

VirtualBox 创建虚拟机并安装 Ubuntu 系统详细指南
VirtualBox 创建虚拟机并安装 Ubuntu 系统详细指南 一、准备工作1. 下载 Ubuntu 镜像2. 安装 VirtualBox二、创建虚拟机1. 新建虚拟机2. 分配内存3. 创建虚拟硬盘三、配置虚拟机1. 加载 Ubuntu 镜像2. 调整处理器核心数(可选)3. 启用 3D 加速(图形优化)四、安装 Ubuntu 系统…...
【算法基础】递归算法 - JAVA
一、递归基础 1.1 什么是递归算法 递归算法是一种通过函数调用自身来解决问题的方法。简单来说,就是"自己调用自己"。递归将复杂问题分解为同类的更简单子问题,直到达到易于直接解决的基本情况。 1.2 递归的核心要素 递归算法由两个关键部…...

触想CX-3588工控主板应用于移动AI数字人,赋能新型智能交互
一、行业发展背景 随着AI智能、自主导航和透明屏显示等技术的不断进步,以及用户对“拟人化”、“沉浸式”交互体验的期待,一种新型交互终端——“移动AI数字人”正在加速实现规模化商用。 各大展厅展馆、零售导购、教学政务甚至家庭场景中,移…...

【深入浅出MySQL】之数据类型介绍
【深入浅出MySQL】之数据类型介绍 MySQL中常见的数据类型一览为什么需要如此多的数据类型数值类型BIT(M)类型INT类型TINYINT类型BIGINT类型浮点数类型float类型DECIMAL(M,D)类型区别总结 字符串类型CHAR类型VARCHAR(M)类型 日期和时间类型enum和set类型 …...