Rust JSON-RPC库op-alloy-rpc-jsonrpsee的使用,支持高效异步RPC通信与Alloy框架集成
op-alloy-rpc-jsonrpsee
低层级的Optimism JSON-RPC服务器和客户端实现。
元数据
包:cargo/op-alloy-rpc-jsonrpsee@0.19.0
大约6小时前
版本:1.86.0
许可证:MIT OR Apache-2.0
大小:16.2 KiB
安装
在您的项目目录中运行以下Cargo命令:
cargo add op-alloy-rpc-jsonrpsee
或者在您的Cargo.toml中添加以下行:
op-alloy-rpc-jsonrpsee = “0.19.0”
文档
文档地址
仓库
代码仓库地址
所有者
alloy-rs/core Matthias Seitz refcell clabby Emilia Hane
完整示例demo:
// Cargo.toml
[dependencies]
op-alloy-rpc-jsonrpsee = "0.19.0"
jsonrpsee = { version = "0.19", features = ["server", "client", "http-client", "http-server", "ws-client", "ws-server"] }
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
// main.rs
use jsonrpsee::{
server::ServerBuilder,
core::Error,
http_client::{HttpClient, HttpClientBuilder},
proc_macros::rpc,
};
use op_alloy_rpc_jsonrpsee::{
optimism::{OptimismApiServer, OptimismApi},
types::*,
};
use std::net::SocketAddr;
// 定义RPC方法
#[rpc(server, client)]
pub trait MyOptimismApi {
#[method(name = "my_customMethod")]
async fn my_custom_method(&self, param: String) -> Result<String, Error>;
}
// 实现RPC方法
pub struct MyOptimismApiImpl;
impl MyOptimismApiServer for MyOptimismApiImpl {
async fn my_custom_method(&self, param: String) -> Result<String, Error> {
Ok(format!("Received: {}", param))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建服务器
let server_addr: SocketAddr = "127.0.0.1:9944".parse().unwrap();
let server = ServerBuilder::default()
.build(server_addr)
.await?;
let api = MyOptimismApiImpl;
let server_handle = server.start(api.into_rpc())?;
// 创建客户端
let client = HttpClientBuilder::default()
.build("http://127.0.0.1:9944")?;
let client = MyOptimismApiClient::new(client);
// 调用RPC方法
let response = client.my_custom_method("test_param".to_string()).await?;
println!("Server response: {}", response);
// 保持服务器运行
server_handle.stopped().await;
Ok(())
}
1 回复
Rust JSON-RPC库op-alloy-rpc-jsonrpsee使用指南
概述
op-alloy-rpc-jsonrpsee是一个专为Rust设计的JSON-RPC库,提供高效的异步RPC通信能力,并与Alloy框架深度集成。该库基于jsonrpsee构建,支持客户端和服务器端的RPC通信,特别适合需要高性能异步处理的区块链和分布式应用场景。
主要特性
- 完全异步设计,基于async/await语法
- 与Alloy框架无缝集成
- 支持HTTP和WebSocket传输协议
- 类型安全的RPC方法调用
- 可扩展的中间件系统
安装方法
在Cargo.toml中添加依赖:
[dependencies]
op-alloy-rpc-jsonrpsee = "0.1"
tokio = { version = "1.0", features = ["full"] }
基本使用方法
1. 创建RPC服务器
use op_alloy_rpc_jsonrpsee::server::{ServerBuilder, ServerHandle};
use jsonrpsee::core::Error;
use jsonrpsee::proc_macros::rpc;
#[rpc(server)]
pub trait MyRpc {
#[method(name = "say_hello")]
async fn say_hello(&self, name: String) -> Result<String, Error>;
}
struct MyRpcServer;
impl MyRpcServer for MyRpcServer {
async fn say_hello(&self, name: String) -> Result<String, Error> {
Ok(format!("Hello, {}!", name))
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let server = ServerBuilder::default()
.build("127.0.0.1:9944")
.await?;
let handle = server.start(MyRpcServer.into_rpc())?;
handle.stopped().await;
Ok(())
}
2. 创建RPC客户端
use op_alloy_rpc_jsonrpsee::client::ClientBuilder;
use jsonrpsee::core::client::ClientT;
use jsonrpsee::rpc_params;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = ClientBuilder::default()
.build("http://127.0.0.1:9944")
.await?;
let response: String = client
.request("say_hello", rpc_params!["World"])
.await?;
println!("Server response: {}", response);
Ok(())
}
3. 与Alloy框架集成示例
use op_alloy_rpc_jsonrpsee::alloy_integration::AlloyRpcExt;
use alloy::providers::ProviderBuilder;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 创建支持JSON-RPC的Alloy Provider
let provider = ProviderBuilder::new()
.with_jsonrpc_client("http://localhost:8545")
.await?;
// 使用Alloy框架的标准方法
let block_number = provider.get_block_number().await?;
println!("Current block number: {}", block_number);
Ok(())
}
高级功能
自定义中间件
use op_alloy_rpc_jsonrpsee::middleware::{Middleware, Next};
use jsonrpsee::core::server::rpc_module::Methods;
struct LoggingMiddleware;
impl Middleware for LoggingMiddleware {
async fn call(&self, request: &str, next: Next<'_>) -> Result<String, Error> {
println!("Received request: {}", request);
let response = next.call(request).await;
println!("Sending response: {:?}", response);
response
}
}
// 在服务器构建时添加中间件
let server = ServerBuilder::default()
.with_middleware(LoggingMiddleware)
.build("127.0.0.1:9944")
.await?;
批量请求处理
use op_alloy_rpc_jsonrpsee::client::BatchRequestBuilder;
let batch = BatchRequestBuilder::new()
.add_request("method1", rpc_params![1, 2, 3])
.add_request("method2", rpc_params!["test"])
.build();
let results: Vec<serde_json::Value> = client.batch_request(batch).await?;
错误处理
use op_alloy_rpc_jsonrpsee::error::RpcError;
match client.request("some_method", rpc_params![]).await {
Ok(result) => println!("Success: {:?}", result),
Err(RpcError::RequestTimeout) => eprintln!("Request timed out"),
Err(RpcError::TransportError(e)) => eprintln!("Transport error: {}", e),
Err(e) => eprintln!("Other error: {}", e),
}
性能优化建议
- 使用连接池管理客户端连接
- 合理配置超时时间
- 启用压缩减少网络传输
- 使用批处理请求减少网络往返
这个库为Rust开发者提供了强大的JSON-RPC功能,特别适合需要高性能异步通信和与Alloy框架集成的应用场景。
完整示例代码
以下是一个完整的RPC服务器和客户端交互示例:
Cargo.toml
[package]
name = "op-alloy-rpc-demo"
version = "0.1.0"
edition = "2021"
[dependencies]
op-alloy-rpc-jsonrpsee = "0.1"
jsonrpsee = { version = "0.18", features = ["server", "client", "macros"] }
tokio = { version = "1.0", features = ["full"] }
anyhow = "1.0"
serde_json = "1.0"
src/main.rs
use op_alloy_rpc_jsonrpsee::server::{ServerBuilder, ServerHandle};
use op_alloy_rpc_jsonrpsee::client::ClientBuilder;
use jsonrpsee::core::Error;
use jsonrpsee::proc_macros::rpc;
use jsonrpsee::core::client::ClientT;
use jsonrpsee::rpc_params;
// 定义RPC trait
#[rpc(server)]
pub trait DemoRpc {
#[method(name = "greet")]
async fn greet(&self, name: String) -> Result<String, Error>;
#[method(name = "add")]
async fn add(&self, a: i32, b: i32) -> Result<i32, Error>;
}
// 实现RPC服务器
struct DemoRpcServer;
impl DemoRpcServer for DemoRpcServer {
async fn greet(&self, name: String) -> Result<String, Error> {
Ok(format!("Hello, {}! Welcome to JSON-RPC", name))
}
async fn add(&self, a: i32, b: i32) -> Result<i32, Error> {
Ok(a + b)
}
}
// 服务器端代码
async fn run_server() -> anyhow::Result<ServerHandle> {
println!("Starting RPC server on 127.0.0.1:9944...");
let server = ServerBuilder::default()
.build("127.0.0.1:9944")
.await?;
let handle = server.start(DemoRpcServer.into_rpc())?;
println!("Server started successfully!");
Ok(handle)
}
// 客户端代码
async fn run_client() -> anyhow::Result<()> {
println!("Connecting to RPC server...");
let client = ClientBuilder::default()
.build("http://127.0.0.1:9944")
.await?;
// 单个请求示例
let greeting: String = client
.request("greet", rpc_params!["Alice"])
.await?;
println!("Greeting response: {}", greeting);
let sum: i32 = client
.request("add", rpc_params![5, 3])
.await?;
println!("Addition result: 5 + 3 = {}", sum);
// 批量请求示例
use op_alloy_rpc_jsonrpsee::client::BatchRequestBuilder;
let batch = BatchRequestBuilder::new()
.add_request("greet", rpc_params!["Bob"])
.add_request("add", rpc_params![10, 20])
.build();
let results: Vec<serde_json::Value> = client.batch_request(batch).await?;
println!("Batch results: {:?}", results);
Ok(())
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 启动服务器
let server_handle = run_server().await?;
// 等待服务器完全启动
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
// 运行客户端测试
if let Err(e) = run_client().await {
eprintln!("Client error: {}", e);
}
// 关闭服务器
server_handle.stop()?;
server_handle.stopped().await;
println!("Demo completed successfully!");
Ok(())
}
运行说明:
- 将上述代码保存到项目中
- 运行
cargo run
启动示例 - 程序将自动启动服务器、执行客户端请求并显示结果
这个完整示例展示了:
- RPC服务器的创建和启动
- RPC客户端的连接和请求
- 单个方法和批量请求的使用
- 完整的错误处理和资源清理