echo_server_v1/
echo_server_v1.rs1use std::sync::Arc;
16use std::time::Duration;
17use tokio::io::{AsyncReadExt, AsyncWriteExt};
18use tokio::net::TcpStream;
19use tokio::sync::oneshot;
20use zerust::datapack::DataPack;
21use zerust::{DefaultRouter, Response, Server};
22
23#[tokio::main]
24async fn main() -> Result<(), Box<dyn std::error::Error>> {
25 let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>();
31
32 let router = Arc::new(DefaultRouter::new());
36
37 let router_clone = router.clone();
39 router_clone.add_route(1, |req| {
40 println!("Received echo request: {:?}", req.data());
41 Response::new(req.msg_id(), req.data().to_vec()) });
43
44 let server = Server::new("127.0.0.1:8000", router);
48 let server_handle = tokio::spawn(async move {
49 if let Err(e) = server.run(shutdown_rx).await {
50 eprintln!("[Zerust] Server runtime error: {}", e);
51 }
52 });
53
54 if let Err(_) = wait_for_server(8000, Duration::from_secs(5)).await {
59 eprintln!("[Client] Failed to connect to server within 5 seconds.");
60 return Err("Server did not start in time".into());
61 }
62 println!("[Client] Server is ready. Proceeding with test...");
63
64 match client().await {
68 Ok(()) => println!("✅ Client finished successfully."),
69 Err(e) => eprintln!("❌ Client error: {}", e),
70 }
71
72 let _ = shutdown_tx.send(());
77 println!("[Main] Shutdown signal sent.");
78
79 let _ = server_handle.await;
84
85 println!("🎉 Program exited gracefully.");
86 Ok(())
87}
88
89async fn client() -> Result<(), Box<dyn std::error::Error>> {
91 let mut stream = TcpStream::connect("127.0.0.1:8000").await?;
92 println!("Connected to server");
93
94 let bytes = DataPack::pack(1, b"test");
96 stream.write_all(&bytes).await?;
97 println!("Sent request: msg_id=1, data=test");
98
99 let mut header = [0u8; 8];
101 stream.read_exact(&mut header).await?;
102 let (msg_id, data_len) = DataPack::unpack_header(&header)?;
103 println!(
104 "Received response header: msg_id={}, data_len={}",
105 msg_id, data_len
106 );
107
108 let mut data = vec![0u8; data_len as usize];
110 stream.read_exact(&mut data).await?;
111 println!(
112 "Received response: msg_id={}, data={:?}",
113 msg_id,
114 String::from_utf8_lossy(&data)
115 );
116
117 Ok(())
118}
119
120async fn wait_for_server(port: u16, timeout: Duration) -> Result<(), Box<dyn std::error::Error>> {
130 let deadline = tokio::time::Instant::now() + timeout;
131 loop {
132 let connect_fut = TcpStream::connect(("127.0.0.1", port));
134 if tokio::time::timeout(deadline - tokio::time::Instant::now(), connect_fut)
135 .await
136 .is_ok()
137 {
138 return Ok(()); }
140 tokio::time::sleep(Duration::from_millis(10)).await;
142 }
143}