# rpc **Repository Path**: luomin5417/rpc ## Basic Information - **Project Name**: rpc - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-20 - **Last Updated**: 2025-08-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## JSON-RPC C 客户端/服务器示例工程 本工程实现了一个基于 TCP 的 JSON-RPC 2.0 客户端与服务器,使用 C11 与内置的 cJSON 库完成消息编解码,展示了参数序列化、错误处理、方法派发和可扩展的远程函数实现方式。 ### 功能特性 - **JSON-RPC 2.0**: 请求/响应遵循 `jsonrpc: "2.0"` 规范 - **可扩展方法表**: 通过 `server/server.c` 中的 `method_map` 注册新方法 - **多类型参数**: 客户端用格式串传参,支持 `int32`、`double`、`string`、以及结构体 `UserProfile` - **错误处理**: 覆盖解析错误、无效请求、方法不存在、参数错误等 - **零外部依赖**: 自带 `lib/cJSON.[ch]`,用 `gcc` 与 `make` 即可构建 ### 目录结构 ``` build/ # 编译产物(目标文件与可执行文件) ├─ rpc_server └─ rpc_client client/ └─ client.c # 客户端示例,演示多种 RPC 调用 server/ ├─ server.c # 服务器主循环与方法派发 ├─ remote_functions.c# 远程方法实现 └─ remote_functions.h common/ ├─ common.h # 公共常量与类型(端口、缓冲区、错误码、UserProfile 等) ├─ rpc_protocol.c # JSON-RPC 请求/响应构造与解析 └─ rpc_protocol.h lib/ ├─ cJSON.c # cJSON 实现(已内置) └─ cJSON.h Makefile # 构建脚本(gcc, C11) README.md ``` ### 环境要求 - Linux(示例使用的是类 Unix Socket API) - gcc(支持 C11) - make ### 构建 ```bash make ``` 构建完成后会在 `build/` 目录下生成可执行文件: - `build/rpc_server` - `build/rpc_client` 清理: ```bash make clean ``` ### 运行 默认服务端监听端口定义在 `common/common.h` 的 `SERVER_PORT`(当前为 8888)。 1) 启动服务器(终端 1) ```bash ./build/rpc_server ``` 2) 运行客户端(终端 2) ```bash ./build/rpc_client ``` 客户端将依次演示: - `add(10, 25)` - `getUserInfo("Alice")` - `sumAndPrint(1.1, "world", 2.2, 3)`(会对数字求和,忽略非数字) - `processUserProfile(UserProfile{"Bob", 42, "New York"})` - 调用不存在的方法以演示错误返回 ### 协议与消息格式 请求示例(调用 `add(10, 25)`,请求 id 为 1): ```json {"jsonrpc":"2.0","method":"add","params":[10,25],"id":1} ``` 成功响应示例: ```json {"jsonrpc":"2.0","result":35,"id":1} ``` 错误响应示例(方法不存在): ```json {"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found"},"id":1} ``` ### 服务端已提供的方法 - `add`:参数 `[number, number]`,返回两数之和 - `getUserInfo`:参数 `[string]`(用户名),返回用户对象 `{name, age, city}`(示例数据) - `sumAndPrint`:参数为数组(可混合类型),对其中所有数值求和并返回 - `processUserProfile`:参数 `[object]`(包含 `name/age/city`),返回确认信息字符串 方法注册位置:`server/server.c` 的 `method_map`。 ### 客户端调用接口说明 核心构造函数(见 `common/rpc_protocol.h`): ```c char* create_json_rpc_request(const char* method_name, int32_t request_id, const char* param_format, ...); ``` `param_format` 使用以下格式字符序列化变参(按顺序匹配): - `i`:`int32_t` - `d`:`double` - `s`:`const char*` - `S`:`const UserProfile*`(结构体会被序列化为 JSON 对象) `UserProfile` 定义(见 `common/common.h`): ```c typedef struct { char name[64]; int32_t age; char city[64]; } UserProfile; ``` 解析响应(见 `common/rpc_protocol.c`): ```c cJSON* parse_json_rpc_response(const char* response_str, int32_t expected_id); ``` ### 扩展:新增一个 RPC 方法的步骤 1. 在 `server/remote_functions.h` 中声明新方法,签名: ```c cJSON* your_method_name(const cJSON* params, RpcErrorCode* error_code); ``` 2. 在 `server/remote_functions.c` 中实现,先校验 `params`,失败时设置 `*error_code = RPC_INVALID_PARAMS` 并返回 `NULL`;成功时返回一个 `cJSON*`(由调用方接管内存)。 3. 在 `server/server.c` 的 `method_map` 中添加映射: ```c {"yourMethod", your_method_name}, ``` 4. 重新编译并运行:`make && ./build/rpc_server` ### 配置与常量 - 端口:`SERVER_PORT`(`common/common.h`,默认 8888) - 缓冲区:`MAX_BUFFER_SIZE`(默认 4096) - 连接等待队列:`MAX_CONNECTIONS_QUEUE` - JSON-RPC 版本:`RPC_JSON_VERSION`(固定为 "2.0") ### 常见问题排查 - 服务器端口被占用:修改 `common/common.h` 中的 `SERVER_PORT`,`make clean && make` 后重试 - 连接失败(客户端):确认服务器已启动,且本机 `127.0.0.1:SERVER_PORT` 可达 - JSON 解析错误:检查请求是否满足 JSON-RPC 2.0 字段要求 ### 致谢 - 本项目内置并使用 `cJSON`(作者 Dave Gamble),文件位于 `lib/`