rpc_client_server/
rpc_client_server.rs1use 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}