rpc_client_server/
rpc_client_server.rs

1//! Example demonstrating RpcClient and RpcServer with SharedMemory transport.
2
3use serde::{Deserialize, Serialize};
4use std::env;
5use std::sync::Arc;
6use xrpc::{
7    MessageChannelAdapter, RpcClient, RpcServer, SharedMemoryConfig, SharedMemoryFrameTransport,
8};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11struct AddRequest {
12    a: i32,
13    b: i32,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17struct AddResponse {
18    result: i32,
19}
20
21#[derive(Debug, Clone, Serialize, Deserialize)]
22struct EchoRequest {
23    message: String,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
27struct EchoResponse {
28    message: String,
29    length: usize,
30}
31
32const SERVICE_NAME: &str = "rpc_example_service";
33
34#[tokio::main]
35async fn main() -> Result<(), Box<dyn std::error::Error>> {
36    let args: Vec<String> = env::args().collect();
37    let mode = args.get(1).map(|s| s.as_str()).unwrap_or("server");
38
39    match mode {
40        "server" => run_server().await?,
41        "client" => run_client().await?,
42        _ => {
43            eprintln!("Usage: cargo run --example rpc_client_server -- [server|client]");
44            std::process::exit(1);
45        }
46    }
47
48    Ok(())
49}
50
51async fn run_server() -> Result<(), Box<dyn std::error::Error>> {
52    println!("[Server] Starting RPC server");
53
54    let config = SharedMemoryConfig::default();
55    let transport = SharedMemoryFrameTransport::create_server(SERVICE_NAME, config)?;
56    let channel = Arc::new(MessageChannelAdapter::new(transport));
57
58    let server = RpcServer::new();
59
60    server.register_typed("add", |req: AddRequest| async move {
61        println!("[Server] add({}, {})", req.a, req.b);
62        Ok(AddResponse {
63            result: req.a + req.b,
64        })
65    });
66
67    server.register_typed("echo", |req: EchoRequest| async move {
68        println!("[Server] echo(\"{}\")", req.message);
69        let len = req.message.len();
70        Ok(EchoResponse {
71            message: req.message,
72            length: len,
73        })
74    });
75
76    println!("[Server] Registered {} handlers", server.handler_count());
77    println!("[Server] Waiting for requests\n");
78
79    server.serve(channel).await?;
80
81    Ok(())
82}
83
84async fn run_client() -> Result<(), Box<dyn std::error::Error>> {
85    println!("[Client] Connecting to RPC server");
86
87    let transport = SharedMemoryFrameTransport::connect_client(SERVICE_NAME)?;
88    let channel = MessageChannelAdapter::new(transport);
89
90    let client = RpcClient::new(channel);
91    let _handle = client.start();
92
93    println!("[Client] Connected!\n");
94
95    println!("[Client] Calling add(10, 32)");
96    let resp: AddResponse = client.call("add", &AddRequest { a: 10, b: 32 }).await?;
97    println!("[Client] Result: {}\n", resp.result);
98
99    println!("[Client] Calling add(100, 200)");
100    let resp: AddResponse = client.call("add", &AddRequest { a: 100, b: 200 }).await?;
101    println!("[Client] Result: {}\n", resp.result);
102
103    println!("[Client] Calling echo(\"Hello, RPC!\")");
104    let resp: EchoResponse = client
105        .call(
106            "echo",
107            &EchoRequest {
108                message: "Hello, RPC!".to_string(),
109            },
110        )
111        .await?;
112    println!(
113        "[Client] Result: message=\"{}\", length={}\n",
114        resp.message, resp.length
115    );
116
117    println!("[Client] Calling unknown method");
118    let result: Result<(), _> = client.call("unknown", &()).await;
119    match result {
120        Ok(_) => println!("[Client] Unexpected success"),
121        Err(e) => println!("[Client] Got expected error: {}\n", e),
122    }
123
124    client.close().await?;
125    println!("[Client] Done!");
126
127    Ok(())
128}