目录
目录README.md

even

Simple RPC Framework

一个简单但功能完整的RPC(远程过程调用)框架,基于Python Socket编程实现,支持跨语言调用、IDL定义和并发处理。

❌✅🧪🚀🎉🌟✨🛑🏓👋📊📖🔹💡📁📡⚙️📤🔧🔍🔄🛠️🔗📋📝🌍

🌟 特性

✅ 核心功能

  • 基于Socket的网络通信 - 使用Python原生Socket API实现
  • 平台化服务管理 - 动态服务注册、发现和管理
  • 多线程并发模型 - 支持并发客户端连接和请求处理
  • 跨语言调用能力 - 基于JSON的标准协议,支持多语言客户端

✅ IDL和代码生成

  • IDL(接口描述语言) - 自定义的服务接口定义语言
  • 多语言代码生成 - 自动生成Python、JavaScript、Java客户端代码
  • 类型安全 - 支持强类型参数和返回值定义

✅ 高级特性

  • 自动服务发现 - 内建服务注册表和服务列表API
  • 错误处理 - 完善的错误处理和异常传播机制
  • 连接管理 - 自动连接超时检测和清理
  • 监控和统计 - 服务调用统计和性能监控

📁 项目结构

RPC/
├── rpc_framework/          # 核心框架代码
│   ├── __init__.py        # 框架入口
│   ├── protocol.py        # RPC协议定义
│   ├── serializer.py      # 消息序列化
│   ├── registry.py        # 服务注册表
│   ├── server.py          # RPC服务器
│   ├── client.py          # RPC客户端
│   └── idl_compiler.py    # IDL编译器
├── examples/              # 示例代码
│   ├── calculator_service.py    # 计算器服务示例
│   ├── calculator_client.py     # 计算器客户端示例
│   ├── calculator.idl           # IDL定义示例
│   ├── idl_demo.py             # IDL编译器演示
│   └── javascript_client_example.js  # JavaScript客户端示例
└── README.md             # 项目文档

🚀 快速开始

1. 运行服务器

# 启动计算器服务
python examples/calculator_service.py

服务器将在 localhost:8888 启动,并注册以下服务:

  • 基本数学运算(加减乘除)
  • 高级数学函数(幂、平方根、阶乘、斐波那契)
  • 工具函数(问候、二次方程求解)

2. 运行客户端

简单的RPC客户端测试:

python examples/simple_test.py

这将运行一系列测试,包括:

  • 加运算
  • 乘运算

全面的RPC客户端测试:

# 测试客户端
python examples/calculator_client.py
  1. 这将运行一系列测试,包括:

    • 基本运算测试

    • 错误处理测试

    • 并发调用测试

    • 内建服务测试

# 测试客户端
python examples/test_rpc_framework.py
  1. 这将运行一系列测试,包括:

    • 测试序列化器功能

    • 测试服务器-客户端通信(一个终端即可)

    • 测试并发调用

    • 内建服务测试

3. 交互式使用

客户端测试完成后,可以选择进入交互模式:

rpc> add 10 20
Result: 30

rpc> sqrt 64
Result: 8.0

rpc> services
Total services: 15
  calc.add: Method from CalculatorService
  calc.subtract: Method from CalculatorService
  ...

rpc> quit

📝 IDL(接口描述语言)

IDL语法示例

service CalculatorService {
    version "1.0.0"
    description "A simple calculator service"
    
    method add(a: float, b: float) -> float {
        description "Add two numbers"
    }
    
    method factorial(n: int) -> int {
        description "Calculate factorial"
    }
    
    method hello(name: string = "World") -> string {
        description "Generate greeting with default parameter"
    }
}

使用IDL编译器

JAVA生成演示:

python ./test_idl_generate_java_client.py

该文件框架包括:

  • 创建IDL编译器实例
  • 解析IDL文件
  • 生成Java客户端代码
  • 保存文件

完整生成演示:

# 运行IDL编译器演示
python examples/idl.py

这将:

  1. 解析 calculator.idl 文件
  2. 解析 示例 内容
  3. 生成多语言客户端代码(Python、Java)
  4. 保存到 examples/generated/ 目录

客户端跨语言调用能力测试

Python客户端:

# 首先启动计算器服务,主要是为了注册服务(前期补充功能后,需要启动,以注册新服务)
python examples/calculator_service.py

# 运行IDL编译器演示,将在 examples/generated/ 目录下生成客户端代码
python examples/idl_demo.py

# 客户端测试
python examples/idl_test/test_cal.py

python examples/idl_test/test_eq.py

python examples/idl_test/test_ut.py

Java客户端:

# 首先启动计算器服务,主要是为了注册服务(前期补充功能后,需要启动,以注册新服务)
python examples/calculator_service.py
    
# 运行IDL编译器演示,将在 examples/generated/ 目录下生成客户端代码
python examples/idl_demo.py

# CalculatorServiceClient.java 在 examples/generated/ 目录下,TestImprovedClient.java 文件在 examples/ 目录下
# 编译
javac ./examples/generated/CalculatorServiceClient.java
javac ./examples/generated/EquationServiceClient.java # 可能会提示warning,无视即可
javac ./examples/generated/UtilityServiceClient.java

cd ./examples
javac -cp "generated" ./test_cal.java
javac -cp "generated" ./test_eq.java
javac -cp "generated" ./test_ut.java
# 运行
java  -cp ".;generated" test_cal
java -cp ".;generated" test_eq
java -cp ".;generated" test_ut

🔧 API参考

RPC服务器

from rpc_framework import RPCServer

# 创建服务器
server = RPCServer(host='localhost', port=8888, max_workers=10)

# 注册单个服务
def my_function(x, y):
    return x + y

server.register_service("add", my_function, "Addition function")

# 批量注册类方法
class MyService:
    def method1(self): pass
    def method2(self): pass

service = MyService()
server.register_class_services(service, prefix="my.")

# 启动服务器
server.start()

RPC客户端

from rpc_framework import RPCClient

# 创建客户端
client = RPCClient(host='localhost', port=8888, timeout=30.0)

# 方式1:手动管理连接
client.connect()
result = client.call("add", 10, 20)
client.disconnect()

# 方式2:使用上下文管理器
with client:
    result = client.call("add", 10, 20)
    
# 内建服务
services = client.list_services()
status = client.get_server_status()
ping_result = client.ping("hello")

IDL编译器

from rpc_framework import IDLCompiler

compiler = IDLCompiler()

# 解析IDL文件
compiler.parse_idl_file("service.idl")

# 或解析IDL内容
idl_content = """
service MyService {
    method test() -> string {
        description "Test method"
    }
}
"""
compiler.parse_idl_content(idl_content)

# 生成客户端代码
python_code = compiler.generate_client_code("MyService", "python")
js_code = compiler.generate_client_code("MyService", "javascript")

# 保存到文件
compiler.save_generated_code("MyService", "python", "./generated")

🌐 跨语言支持

协议格式

框架使用自定义的二进制协议,消息格式如下:

+----------+----------+----------+----------+
| Magic(4) | Type(1)  | Length(4)| Body(N)  |
+----------+----------+----------+----------+
  • Magic: 0x52504321 (“RPC!”)
  • Type: 消息类型(REQUEST/RESPONSE/ERROR/HEARTBEAT)
  • Length: 消息体长度
  • Body: JSON格式的消息体

消息体格式

请求消息:

{
    "method": "service_name",
    "params": [arg1, arg2, ...],
    "id": "request_id"
}

响应消息:

{
    "result": "return_value",
    "id": "request_id"
}

错误消息:

{
    "error": {
        "code": -1,
        "message": "error_description"
    },
    "id": "request_id"
}

🔀 并发模型

服务器并发

  • ThreadPoolExecutor: 使用线程池处理客户端连接
  • 多线程处理: 每个客户端连接在独立线程中处理
  • 连接管理: 自动检测和清理超时连接
  • 线程安全: 服务注册表支持并发访问

客户端并发

  • 异步接收: 独立线程处理服务器响应
  • 请求-响应映射: 通过请求ID关联请求和响应
  • 超时控制: 可配置的请求超时时间
  • 线程安全: 支持多线程环境下的并发调用

🛠️ 扩展和自定义

自定义序列化器

from rpc_framework.serializer import BaseSerializer

class CustomSerializer(BaseSerializer):
    def serialize(self, data):
        # 自定义序列化逻辑
        pass
    
    def deserialize(self, data):
        # 自定义反序列化逻辑
        pass

自定义协议

可以扩展 RPCProtocol 类来支持其他协议格式:

from rpc_framework.protocol import RPCProtocol

class CustomProtocol(RPCProtocol):
    @staticmethod
    def pack_message(msg_type, body):
        # 自定义打包逻辑
        pass

中间件支持

可以在服务调用前后添加中间件:

def logging_middleware(service_name, params, handler):
    print(f"Calling {service_name} with {params}")
    result = handler(*params)
    print(f"Result: {result}")
    return result

# 在服务注册时包装处理器
def wrapped_handler(*args, **kwargs):
    return logging_middleware("my_service", args, original_handler)

📊 性能和限制

性能特点

  • 并发连接: 支持多个客户端同时连接
  • 消息大小: 最大1MB消息体
  • 连接池: 服务器端连接复用
  • 序列化: JSON序列化,跨语言兼容

当前限制

  • 网络协议: 仅支持TCP,不支持UDP
  • 安全性: 未实现身份验证和加密
  • 负载均衡: 未实现服务器集群和负载均衡
  • 持久化: 服务注册信息不持久化

🤝 参考资料

本框架在设计时参考了以下资料:

  • Python Socket编程官方文档 - 网络编程基础
  • 《深入理解计算机系统》 - 网络编程章节
  • gRPC设计思想 - 仅作设计参考,非代码抄袭
  • Protocol Buffers IDL设计 - IDL语法设计参考
  • JSON-RPC规范 - 消息格式参考
  • HTTP/2 frame format - 二进制协议设计参考

📄 许可证

本项目采用MIT许可证 - 详见 LICENSE 文件


作者: Yuhao Wang

版本: 1.0.0

最后更新: 2025年07月

邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

©Copyright 2023 CCF 开源发展委员会
Powered by Trustie& IntelliDE 京ICP备13000930号