Rust JSON-RPC服务器库jsonrpsee-http-server的使用:构建高性能HTTP RPC服务的Rust插件库
Rust JSON-RPC服务器库jsonrpsee-http-server的使用:构建高性能HTTP RPC服务的Rust插件库
安装
在项目目录中运行以下Cargo命令:
cargo add jsonrpsee-http-server
或者在Cargo.toml中添加以下行:
jsonrpsee-http-server = "0.15.1"
完整示例代码
use jsonrpsee_http_server::{HttpServerBuilder, RpcModule};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 创建HTTP服务器
let server = HttpServerBuilder::default()
.build("127.0.0.1:9944")
.await?;
// 创建RPC模块
let mut module = RpcModule::new(());
// 注册RPC方法
module.register_method("say_hello", |_, _| {
Ok("Hello, world!")
})?;
// 注册RPC模块
server.register_module(module)?;
// 启动服务器
server.start().await?;
Ok(())
}
使用方法
- 首先创建HTTP服务器实例,指定监听地址和端口
- 创建一个RpcModule实例来注册RPC方法
- 使用
register_method
方法注册RPC方法 - 将模块注册到服务器
- 启动服务器
文档
官方文档 源代码仓库
许可证
MIT许可证
所有者
- paritytech/Core devs团队
- Niklas Adolfsson
- Parity Crate Owner
- Parity CI Robot
完整示例代码
以下是一个更完整的示例,展示了如何创建一个带有多个RPC方法的JSON-RPC服务器:
use jsonrpsee_http_server::{HttpServerBuilder, RpcModule};
use serde_json::Value;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 创建HTTP服务器,监听本地9944端口
let server = HttpServerBuilder::default()
.build("127.0.0.1:9944")
.await?;
// 创建RPC模块
let mut module = RpcModule::new(());
// 注册简单的问候方法
module.register_method("greet", |params, _| {
let name: String = params.parse()?;
Ok(format!("Hello, {}!", name))
})?;
// 注册带参数的加法方法
module.register_method("add", |params, _| {
let (a, b): (i32, i32) = params.parse()?;
Ok(a + b)
})?;
// 注册获取服务器信息的方法
module.register_method("get_server_info", |_, _| {
Ok(serde_json::json!({
"name": "jsonrpsee-http-server",
"version": "0.15.1"
}))
})?;
// 将模块注册到服务器
server.register_module(module)?;
println!("Server started at http://127.0.0.1:9944");
// 启动服务器
server.start().await?;
Ok(())
}
这个示例展示了:
- 创建多个RPC方法
- 处理不同类型的参数
- 返回不同类型的数据
- 使用serde_json返回结构化数据
要测试这个服务器,可以使用任何JSON-RPC客户端向http://127.0.0.1:9944发送请求。
1 回复
Rust JSON-RPC服务器库jsonrpsee-http-server的使用指南
简介
jsonrpsee-http-server
是一个高性能的Rust库,用于构建JSON-RPC 2.0规范的HTTP服务器。它是jsonrpsee
生态系统的一部分,专注于提供简单易用且高性能的RPC服务实现。
主要特性
- 完全兼容JSON-RPC 2.0规范
- 异步支持(基于tokio)
- 类型安全的RPC方法注册
- 中间件支持
- 低开销和高性能
使用方法
1. 添加依赖
首先在Cargo.toml中添加依赖:
[dependencies]
jsonrpsee-http-server = "0.16"
tokio = { version = "1.0", features = ["full"] }
2. 基本示例
use jsonrpsee_http_server::{RpcModule, ServerBuilder};
use std::net::SocketAddr;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 创建RPC模块
let mut module = RpcModule::new(());
// 注册RPC方法
module.register_method("say_hello", |_, _| {
Ok("Hello from JSON-RPC!")
})?;
// 注册带参数的方法
module.register_method("add", |params, _| {
let (a, b): (i32, i32) = params.parse()?;
Ok(a + b)
})?;
// 构建服务器
let server = ServerBuilder::default()
.build("127.0.0.1:9944")
.await?;
// 启动服务器
let addr = server.local_addr()?;
println!("Server running at {}", addr);
// 等待服务器关闭
server.start(module).await?;
Ok(())
}
3. 带上下文的高级示例
use jsonrpsee_http_server::{RpcModule, ServerBuilder};
use std::sync::Arc;
struct MyContext {
shared_data: String,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let ctx = Arc::new(MyContext {
shared_data: "some shared state".to_string(),
});
let mut module = RpcModule::new(ctx);
module.register_method("get_shared_data", |_, ctx| {
Ok(ctx.shared_data.clone())
})?;
module.register_method("echo", |params, _| {
let input: String = params.parse()?;
Ok(input)
})?;
let server = ServerBuilder::default()
.build("127.0.0.1:9944")
.await?;
println!("Server running at {}", server.local_addr()?);
server.start(module).await?;
Ok(())
}
4. 订阅方法示例
jsonrpsee-http-server
也支持发布-订阅模式:
use jsonrpsee_http_server::{RpcModule, ServerBuilder, SubscriptionSink};
use jsonrpsee_core::Error;
use tokio::sync::broadcast;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let (tx, _) = broadcast::channel(16);
let mut module = RpcModule::new(tx);
module.register_subscription("subscribe_events", "subscribe", "unsubscribe", |mut sink, tx| async move {
let mut rx = tx.subscribe();
while let Ok(event) = rx.recv().await {
if let Err(err) = sink.send(&event) {
eprintln!("Failed to send event: {}", err);
break;
}
}
Ok(())
})?;
let server = ServerBuilder::default()
.build("127.极客时间Rust训练营0.0.1:9944")
.await?;
println!("Server running at {}", server.local_addr()?);
server.start(module).await?;
Ok(())
}
配置选项
ServerBuilder
提供了多种配置选项:
let server = ServerBuilder::default()
.max_request_body_size(1024 * 1024) // 1MB
.max_response_body_size(1024 * 1024) // 1MB
.set_http_middleware(/* 自定义中间件 */)
.cors(/* CORS配置 */)
.build("127.0.0.1:9944")
.await?;
客户端调用示例
使用curl测试服务器:
# 调用say_hello方法
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"say_hello","id":1}' http://localhost:9944
# 调用add方法
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"add","params":[2,3],"id":1}' http://localhost:9944
性能优化建议
- 使用
Arc
共享大型上下文数据 - 对于CPU密集型任务,考虑使用
tokio::task::spawn_blocking
- 合理设置请求和响应体大小限制
- 使用连接池管理下游服务连接
jsonrpsee-http-server
是一个强大而灵活的库,可以轻松构建高性能的JSON-RPC服务。通过合理设计RPC接口和利用Rust的类型系统,可以创建既安全又高效的远程过程调用服务。
完整示例代码
下面是一个完整的JSON-RPC服务器示例,包含基本方法、上下文共享和订阅功能:
use jsonrpsee_http_server::{RpcModule, ServerBuilder, SubscriptionSink};
use jsonrpsee_core::Error;
use std::sync::Arc;
use tokio::sync::broadcast;
// 定义共享的上下文
struct AppState {
counter: u64,
event_tx: broadcast::Sender<String>,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 创建事件广播通道
let (event_tx, _) = broadcast::channel(16);
// 创建共享上下文
let ctx = Arc::new(AppState {
counter: 0,
event_tx,
});
// 创建RPC模块
let mut module = RpcModule::new(ctx.clone());
// 注册简单方法
module.register_method("greet", |params, _| {
let name: String = params.parse().unwrap_or("world".into());
Ok(format!("Hello, {}!", name))
})?;
// 注册带状态的方法
module.register_method("increment", |_, ctx| {
let mut ctx = Arc::make_mut(&mut Arc::clone(&ctx));
ctx.counter += 1;
Ok(ctx.counter)
})?;
// 注册订阅方法
module.register_subscription(
"events",
"subscribe_events",
"unsubscribe_events",
|mut sink, ctx| async move {
let mut rx = ctx.event_tx.subscribe();
// 发送初始事件
if let Err(e) = sink.send(&"Subscription started".to_string()) {
eprintln!("Failed to send initial event: {}", e);
return Ok(());
}
// 处理事件流
while let Ok(event) = rx.recv().await {
if let Err(e) = sink.send(&event) {
eprintln!("Failed to send event: {}", e);
break;
}
}
Ok(())
},
)?;
// 启动后台任务发送事件
tokio::spawn(async move {
let mut count = 0;
loop {
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
count += 1;
let _ = ctx.event_tx.send(format!("Event {}", count));
}
});
// 构建并启动服务器
let server = ServerBuilder::default()
.max_request_body_size(1024 * 1024)
.build("127.0.0.1:9944")
.await?;
println!("Server running at {}", server.local_addr()?);
server.start(module).await?;
Ok(())
}
这个完整示例展示了:
- 基本RPC方法调用
- 共享状态的修改
- 发布-订阅模式
- 后台任务生成事件
- 服务器配置选项
您可以使用curl测试这些端点:
# 测试greet方法
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"greet","params":["Rust"],"id":1}' http://localhost:9944
# 测试increment方法
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"increment","id":1}' http://localhost:9944
# 测试订阅(使用websocket客户端)