rpc_client_server/
rpc_client_server.rs

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