diff options
Diffstat (limited to 'game_server/src')
-rw-r--r-- | game_server/src/backend_connection.rs | 57 | ||||
-rw-r--r-- | game_server/src/game_logger.rs | 29 | ||||
-rw-r--r-- | game_server/src/gameserver.rs | 33 | ||||
-rw-r--r-- | game_server/src/main.rs | 5 |
4 files changed, 104 insertions, 20 deletions
diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index 9307c4a..11642f2 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -1,31 +1,68 @@ use reqwest::{Response, Client, Url, UrlError, Error as ReqError}; +use std::sync::mpsc::{Sender, Receiver}; +use std::sync::mpsc; +use super::gameserver::Token; pub struct BackendConnection { host: String, - client: Client, - last_response: Option<Result<Response, ReqError>> + req_sender: Sender<RequestData>, + res_rec: Receiver<ResponseResult>, } +#[derive(Debug)] +pub enum BackendError { + UrlError(UrlError), + RequestError(ReqError), + InvalidTokenFormat, + InvalidToken, +} + +pub type TokenValidity = Result<(), BackendError>; +pub type RequestData = Url; +pub type ResponseResult = Result<Response, ReqError>; + impl BackendConnection { + fn run_background(req_rec: Receiver<RequestData>, res_sender: Sender<ResponseResult>) { + let client = Client::new(); + loop { + let request_data = req_rec.recv().unwrap(); + let location = request_data; + let request = client.get(location); + let response = request.send(); + res_sender.send(response).unwrap(); + } + } + pub fn new(host: &str) -> Self { + let (req_sender, req_rec): (Sender<RequestData>, Receiver<RequestData>) + = mpsc::channel(); + let (res_sender, res_rec): (Sender<ResponseResult>, Receiver<ResponseResult>) + = mpsc::channel(); + std::thread::spawn(move || Self::run_background(req_rec, res_sender)); BackendConnection { host: host.to_string(), - client: Client::new(), - last_response: None + req_sender, + res_rec, } } - pub fn request(&mut self, location: &str) -> Result<(), UrlError> { - Ok(self.last_response = - Some(self.client.get(Url::parse(&format!("{}{}", self.host, location))?) - .send())) + pub fn request(&self, location: &str) -> Result<(), UrlError> { + Ok(self.req_sender.send(Url::parse(&format!("{}{}", self.host, location))?).unwrap()) } - pub fn get_response(&self) -> &Option<Result<Response, ReqError>> { - &self.last_response + pub fn get_response(&self) -> ResponseResult { + self.res_rec.recv().unwrap() } pub fn host_name<'a>(&'a self) -> &'a str { &self.host } + + pub fn validate_token(&self, token: &Token) -> TokenValidity { + let location = format!("/api/lobby/tokens/{}", token); + self.request(&location).map_err(|err| BackendError::UrlError(err))?; + let response = self.get_response(); + println!("backend response: {:?}", response); + Ok(()) + } } diff --git a/game_server/src/game_logger.rs b/game_server/src/game_logger.rs new file mode 100644 index 0000000..e49ebe8 --- /dev/null +++ b/game_server/src/game_logger.rs @@ -0,0 +1,29 @@ +use colored::*; + +fn color_level(level: log::Level) -> colored::ColoredString { + let text = format!("{: <8}", level); + match level { + log::Level::Error => text.red().bold(), + log::Level::Warn => text.yellow(), + log::Level::Info => text.green(), + log::Level::Debug => text.cyan(), + log::Level::Trace => text.magenta(), + } +} + +pub fn init_logger() { + fern::Dispatch::new().format(|out, message, record|{ + out.finish(format_args!( + "{} {} > {}", + color_level(record.level()), + record.target(), + message + ) + ) + }) + .level(log::LevelFilter::Debug) + .level_for("hyper", log::LevelFilter::Off) + .level_for("tokio-reactor", log::LevelFilter::Off) + .chain(std::io::stdout()) + .apply().unwrap(); +} diff --git a/game_server/src/gameserver.rs b/game_server/src/gameserver.rs index 9334a27..a4b1ed5 100644 --- a/game_server/src/gameserver.rs +++ b/game_server/src/gameserver.rs @@ -4,14 +4,16 @@ use websocket::{OwnedMessage, server::{NoTlsAcceptor, InvalidConnection, sync::AcceptResult}}; use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; -use std::sync::mpsc; -use std::sync::mpsc::{Sender, Receiver}; +use std::sync::{mpsc, + mpsc::{Sender, Receiver}, + Arc, Mutex}; +use std::collections::HashMap; use super::lobby::Lobby; use super::backend_connection::BackendConnection; const PROTOCOL: &str = "tuesday"; -type Token = u32; +pub type Token = u32; #[derive(Debug)] pub enum GameServerError { @@ -24,7 +26,8 @@ pub enum GameServerError { pub struct GameServer { addr: SocketAddr, lobby: Lobby, - backend: BackendConnection, + backend: Arc<Mutex<BackendConnection>>, + clients: Arc<Mutex<HashMap<Token, GameClient>>>, } pub struct GameClient { @@ -47,7 +50,7 @@ impl GameClient { .recv_message() .ok()?; if let OwnedMessage::Text(text) = message { - text.parse::<Token>().ok() + text.parse().ok() } else { None } @@ -67,7 +70,8 @@ impl GameServer { GameServer { addr, lobby, - backend, + backend: Arc::new(Mutex::new(backend)), + clients: Arc::new(Mutex::new(HashMap::new())), } } @@ -81,9 +85,22 @@ impl GameServer { } fn add_client(&self, mut client: GameClient) { + let clients = Arc::clone(&self.clients); + let backend = Arc::clone(&self.backend); std::thread::spawn(move || { - println!("Token: {:?}", client.require_token()); - loop { std::thread::sleep(std::time::Duration::from_millis(100)); } + let token = client.require_token(); + if let Some(token) = token { + println!("Token: {}", token); + let locked_backend = backend.lock().unwrap(); + let result = locked_backend.validate_token(&token); + if let Err(err) = result { + warn!("token {} is invalid: '{:?}'", token, err); + } else { + clients.lock().unwrap().insert(token, client); + } + } else { + warn!("client sent invalid token"); + } }); } diff --git a/game_server/src/main.rs b/game_server/src/main.rs index e129283..76e7a39 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -4,13 +4,14 @@ mod lobby; mod gameserver; mod backend_connection; +mod game_logger; + #[macro_use] extern crate log; -use pretty_env_logger; use backend_connection::BackendConnection; fn main() { - pretty_env_logger::init(); + game_logger::init_logger(); let addr = ("127.0.0.1", 5001); info!("create game server on {:?}", addr); |