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);
};

特性说明

  1. 异步支持:通过add_async_method方法可以添加异步RPC方法
  2. 通知支持:通过add_notification方法可以添加不需要返回值的通知方法
  3. 类型安全:参数可以通过Params类型进行解析
  4. 错误处理:内置了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);
};

性能优化建议

  1. 使用Arc共享大型数据结构而不是克隆
  2. 对于计算密集型方法,考虑使用tokio::task::spawn_blocking
  3. 合理设置WebSocket帧大小限制
  4. 使用连接池管理数据库连接等资源

jsonrpc-ws-server为Rust开发者提供了一个强大而灵活的工具,用于构建高性能的WebSocket RPC服务。通过结合Rust的异步特性和JSON-RPC协议,可以轻松构建高效的分布式系统通信层。

回到顶部