use std::{collections::HashMap, sync::Mutex, time::Duration};
use lynn_tcp::{
lynn_client::LynnClient, lynn_server::*, lynn_state::AppState, lynn_tcp_dependents::*,
};
use tracing_subscriber::fmt;
#[derive(Default)]
struct UserRepo {
users: Mutex<HashMap<u64, String>>,
}
impl UserRepo {
fn new() -> Self {
let mut users = HashMap::new();
users.insert(1, "lynn".to_string());
users.insert(2, "hyper".to_string());
Self {
users: Mutex::new(users),
}
}
fn find_user(&self, id: u64) -> String {
self.users
.lock()
.map(|users| users.get(&id).cloned().unwrap_or_else(|| "unknown".into()))
.unwrap_or_else(|_| "locked".into())
}
}
struct AppConfig {
service_name: String,
}
async fn find_user(repo: AppState<UserRepo>, input_buf_vo: InputBufVO) -> HandlerResult {
let id: u64 = String::from_utf8_lossy(&input_buf_vo.get_all_bytes())
.trim()
.parse()
.unwrap_or(0);
let name = repo.find_user(id);
let addr = input_buf_vo.get_input_addr().unwrap();
HandlerResult::new_with_send(1, name.into(), vec![addr])
}
async fn service_info(config: AppState<AppConfig>, input_buf_vo: InputBufVO) -> HandlerResult {
let addr = input_buf_vo.get_input_addr().unwrap();
HandlerResult::new_with_send(2, config.service_name.clone().into(), vec![addr])
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
fmt::init();
println!("🚀 Starting Lynn TCP global-state example...");
println!();
let _server_handle = tokio::spawn(async {
let _server = LynnServer::new()
.await
.with_state(UserRepo::new())
.with_state(AppConfig {
service_name: "lynn-state-demo".to_string(),
})
.add_router(1, find_user)
.add_router(2, service_info)
.start()
.await;
});
tokio::time::sleep(Duration::from_millis(200)).await;
let mut client = LynnClient::new_with_addr("127.0.0.1:9177")
.await
.start()
.await;
println!("🔌 [client] connected = {}", client.is_connected());
client
.send_data(HandlerResult::new_with_send_to_server(1, "1".into()))
.await?;
if let Some(response) = client.get_receive_data().await {
println!(
"📥 [client] user #1 = {:?}",
String::from_utf8_lossy(&response.get_all_bytes())
);
}
client
.send_data(HandlerResult::new_with_send_to_server(2, "info".into()))
.await?;
if let Some(response) = client.get_receive_data().await {
println!(
"📥 [client] service info = {:?}",
String::from_utf8_lossy(&response.get_all_bytes())
);
}
tokio::time::sleep(Duration::from_millis(100)).await;
println!();
println!("🏁 Global-state example completed successfully!");
Ok(())
}