Rust WebSocket JSON-RPC服务器库jsonrpc-ws-server的使用,实现高效异步RPC通信
Rust WebSocket JSON-RPC服务器库jsonrpc-ws-server的使用,实现高效异步RPC通信
jsonrpc-ws-server是一个用于JSON-RPC 2.0的WebSocket服务器库。
示例
Cargo.toml
[dependencies]
jsonrpc-ws-server = "15.0"
main.rs
use jsonrpc_ws_server::*;
use jsonrpc_ws_server::jsonrpc_core::*;
fn main() {
let mut io = IoHandler::new();
io.add_method("say_hello", |_params| {
Ok(Value::String("hello".into()))
});
let server = ServerBuilder::new(io)
.start(&"0.0.0.0:3030".parse().unwrap())
.expect("Server must start with no issues");
server.wait().unwrap()
}
完整示例代码
下面是一个更完整的异步RPC通信示例,包含多个RPC方法和错误处理:
use jsonrpc_ws_server::*;
use jsonrpc_ws_server::jsonrpc_core::*;
use jsonrpc_ws_server::jsonrpc_core::futures::Future;
use std::thread;
fn main() {
// 创建IO处理器
let mut io = IoHandler::new();
// 添加同步方法
io.add_method("say_hello", |params: Params| {
match params.parse::<String>() {
Ok(name) => Ok(Value::String(format!("Hello, {}!", name))),
Err(_) => Ok(Value::String("Hello, stranger!".into()))
}
});
// 添加异步方法
io.add_async_method("async_echo", |params: Params| {
params.parse::<String>()
.map(|msg| {
thread::sleep(std::time::Duration::from_secs(1)); // 模拟耗时操作
futures::future::ok(Value::String(msg))
})
.unwrap_or_else(|_| futures::future::ok(Value::String("".into())))
});
// 添加通知方法(不需要返回值)
io.add_notification("log_message", |params: Params| {
println!("Received log message: {:?}", params);
});
// 启动服务器
let server = ServerBuilder::new(io)
.start(&"0.0.0.0:3030".parse().unwrap())
.expect("Unable to start RPC server");
println!("Server running at ws://0.0.0.0:3030");
// 等待服务器关闭
server.wait().unwrap();
}
客户端测试代码
你可以使用以下JavaScript代码测试这个RPC服务器:
const ws = new WebSocket('ws://localhost:3030');
ws.onopen = () => {
// 调用同步方法
ws.send(JSON.stringify({
jsonrpc: "2.0",
method: "say_hello",
params: ["World"],
id: 1
}));
// 调用异步方法
ws.send(JSON.stringify({
jsonrpc: "2.0",
method: "async_echo",
params: ["Async message"],
id: 2
}));
// 发送通知(不需要响应)
ws.send(JSON.stringify({
jsonrpc: "2.0",
method: "log_message",
params: ["This is a log message"]
}));
};
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
console.log("Received response:", response);
};
特性说明
- 异步支持:通过
add_async_method
方法可以添加异步RPC方法 - 通知支持:通过
add_notification
方法可以添加不需要返回值的通知方法 - 类型安全:参数可以通过
Params
类型进行解析 - 错误处理:内置了JSON-RPC标准错误处理机制
这个库非常适合需要高效异步通信的RPC应用场景,特别是基于WebSocket的实时应用。
1 回复
Rust WebSocket JSON-RPC服务器库jsonrpc-ws-server的使用指南
jsonrpc-ws-server
是一个基于Rust的WebSocket JSON-RPC服务器实现库,提供了高效的异步RPC通信能力。这个库是jsonrpc
套件的一部分,专门用于WebSocket协议上的JSON-RPC通信。
主要特性
- 完全异步设计,基于
tokio
运行时 - 支持WebSocket协议上的JSON-RPC 2.0规范
- 可扩展的请求处理机制
- 内置会话管理
- 与
jsonrpc-core
兼容
基本使用方法
添加依赖
首先在Cargo.toml
中添加依赖:
[dependencies]
jsonrpc-ws-server = "18.0"
jsonrpc-core = "18.0"
futures = "0.3"
创建基本服务器
use jsonrpc_ws_server::*;
use jsonrpc_core::*;
fn main() {
let mut io = IoHandler::new();
// 添加RPC方法
io.add_method("say_hello", |_params| async {
Ok(Value::String("hello".to_string()))
});
// 启动服务器
let server = ServerBuilder::new(io)
.start(&"127.0.0.1:3030".parse().unwrap())
.expect("Server must start with no issues");
server.wait().unwrap();
}
处理带参数的RPC方法
io.add_method("add", |params: Params| async {
let params: (u64, u64) = params.parse()?;
Ok(Value::Number((params.0 + params.1).into()))
});
高级用法
使用会话(Session)
use jsonrpc_ws_server::{Session, SessionId};
io.add_method("get_session_id", |params: Params| {
let session: Session = params.parse()?;
Ok(Value::String(session.id.to_string()))
});
广播消息给所有客户端
use jsonrpc_ws_server::{MetaExtractor, NoopExtractor, ServerBuilder};
let server = ServerBuilder::with_meta_extractor(io, NoopExtractor)
.session_meta_extractor(|context: &RequestContext| {
// 可以在这里提取会话元数据
Some(())
})
.start(&"127.0.0.1:3030".parse().unwrap())
.expect("Server must start with no issues");
// 获取所有活动会话
let sessions = server.open_sessions();
for session in sessions {
// 向每个会话发送通知
session.send_notification("broadcast_message", &Value::String("Hello all!".into()));
}
处理通知
io.add_notification("log_message", |params: Params| {
if let Ok(msg) = params.one::<String>() {
println!("Received log message: {}", msg);
}
});
完整示例
use jsonrpc_ws_server::*;
use jsonrpc_core::*;
use serde_json::Value;
#[tokio::main]
async fn main() {
let mut io = IoHandler::new();
// 添加方法
io.add_method("add", |params: Params| async {
let (a, b): (i64, i64) = params.parse()?;
Ok(Value::from(a + b))
});
io.add_method("echo", |params: Params| async {
Ok(params.into())
});
// 添加通知
io.add_notification("log", |params: Params| {
if let Ok(msg) = params.one::<String>() {
println!("Client log: {}", msg);
}
});
// 启动服务器
let server = ServerBuilder::new(io)
.start(&"127.0.0.1:3030".parse().unwrap())
.expect("Server failed to start");
println!("Server running at ws://127.0.0.1:3030");
server.wait().unwrap();
}
客户端连接示例
使用JavaScript连接这个服务器的示例:
const ws = new WebSocket('ws://localhost:3030');
ws.onopen = () => {
// 调用RPC方法
ws.send(JSON.stringify({
jsonrpc: "2.0",
method: "add",
params: [5, 7],
id: 1
}));
// 发送通知
ws.send(JSON.stringify({
jsonrpc: "2.0",
method: "log",
params: ["Hello from client"]
}));
};
ws.onmessage = (event) => {
const response = JSON.parse(event.data);
console.log("Received:", response);
};
性能优化建议
- 使用
Arc
共享大型数据结构而不是克隆 - 对于计算密集型方法,考虑使用
tokio::task::spawn_blocking
- 合理设置WebSocket帧大小限制
- 使用连接池管理数据库连接等资源
jsonrpc-ws-server
为Rust开发者提供了一个强大而灵活的工具,用于构建高性能的WebSocket RPC服务。通过结合Rust的异步特性和JSON-RPC协议,可以轻松构建高效的分布式系统通信层。