From b65c999daa5c83b9e76c6dca9df088a40e440642 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 17:38:50 +0200 Subject: Change logger to fern --- game_server/src/main.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'game_server/src/main.rs') 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); -- cgit v1.2.3-54-g00ecf From 14c163e415a8ad37d9111e6a5a4a34e3cbe0ad74 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 17:55:04 +0200 Subject: Rename gameserver module to server --- game_server/src/backend_connection.rs | 2 +- game_server/src/gameserver.rs | 164 ---------------------------------- game_server/src/main.rs | 4 +- game_server/src/server.rs | 164 ++++++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 167 deletions(-) delete mode 100644 game_server/src/gameserver.rs create mode 100644 game_server/src/server.rs (limited to 'game_server/src/main.rs') diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index 11642f2..fa41791 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -1,7 +1,7 @@ use reqwest::{Response, Client, Url, UrlError, Error as ReqError}; use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; -use super::gameserver::Token; +use super::server::Token; pub struct BackendConnection { host: String, diff --git a/game_server/src/gameserver.rs b/game_server/src/gameserver.rs deleted file mode 100644 index a4b1ed5..0000000 --- a/game_server/src/gameserver.rs +++ /dev/null @@ -1,164 +0,0 @@ -use websocket::{OwnedMessage, - sync::Server, - client::sync::Client, - server::{NoTlsAcceptor, InvalidConnection, - sync::AcceptResult}}; -use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; -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"; - -pub type Token = u32; - -#[derive(Debug)] -pub enum GameServerError { - BindError(std::io::Error), - HandshakeRequestError, - InvalidProtocolError, - AcceptError(std::io::Error) -} - -pub struct GameServer { - addr: SocketAddr, - lobby: Lobby, - backend: Arc>, - clients: Arc>>, -} - -pub struct GameClient { - addr: SocketAddr, - client: Client, -} - -impl GameClient { - fn from_raw(client: Client) -> Result { - let addr = client.peer_addr().map_err(|_| ())?; - info!("got a client connection from: {}", addr); - Ok(GameClient { - addr, - client, - }) - } - - fn require_token(&mut self) -> Option { - let message = self.client - .recv_message() - .ok()?; - if let OwnedMessage::Text(text) = message { - text.parse().ok() - } else { - None - } - } -} - -type ClientConnection = Result; - -impl GameServer { - pub fn new(addr: T) -> Self { - let addr = addr.to_socket_addrs().unwrap().next().unwrap(); - debug!("ws address: {}", addr); - info!("create lobby"); - let lobby = Lobby::new(); - let backend = BackendConnection::new("https://kobert.dev"); - info!("got a C# backend connection"); - GameServer { - addr, - lobby, - backend: Arc::new(Mutex::new(backend)), - clients: Arc::new(Mutex::new(HashMap::new())), - } - } - - pub fn run(&self) -> Result<(), GameServerError> { - let reader = self.read_clients(); - loop { - let mut connection = reader.recv().unwrap()?; - self.add_client(connection); - } - Ok(()) - } - - fn add_client(&self, mut client: GameClient) { - let clients = Arc::clone(&self.clients); - let backend = Arc::clone(&self.backend); - std::thread::spawn(move || { - 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"); - } - }); - } - - fn read_clients(&self) -> Receiver { - let (s, r): (Sender, Receiver) - = mpsc::channel(); - let addr = self.addr; - std::thread::spawn(move || { - let result = Self::handle_requests(addr, &s).or_else(|e| s.send(Err(e))); - }); - r - } - - fn handle_requests(addr: SocketAddr, s: &Sender) -> Result<(), GameServerError> { - let server = match Server::::bind(addr) { - Ok(v) => v, - Err(e) => { - error!("websocket binding error"); - Err(GameServerError::BindError(e))? - }, - }; - info!("webserver is being launched"); - for req in server { - s.send(Ok(Self::handle_request(req)?)).unwrap(); - } - info!("webserver is being shut down"); - Ok(()) - } - - fn handle_request(req: AcceptResult) -> ClientConnection { - match req { - Ok(req) => { - if !req.protocols().contains(&PROTOCOL.to_string()) { - warn!("a client tried to connect without {} protocol", PROTOCOL); - req.reject().unwrap(); - Err(GameServerError::InvalidProtocolError) - } else { - match req.use_protocol(PROTOCOL).accept() { - Ok(client) => { - match GameClient::from_raw(client) { - Ok(client) => Ok(client), - Err(_) => { - error!("could not create a client"); - Err(GameServerError::HandshakeRequestError) - } - } - }, - Err((_, e)) => { - warn!("client handshake failed"); - Err(GameServerError::AcceptError(e)) - } - } - } - }, - Err(e) => { - warn!("invalid client request"); - Err(GameServerError::HandshakeRequestError) - } - } - } -} diff --git a/game_server/src/main.rs b/game_server/src/main.rs index 76e7a39..4d05efe 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -1,7 +1,7 @@ mod group; mod test_group; mod lobby; -mod gameserver; +mod server; mod backend_connection; mod game_logger; @@ -15,7 +15,7 @@ fn main() { let addr = ("127.0.0.1", 5001); info!("create game server on {:?}", addr); - let gameserver = gameserver::GameServer::new(addr); + let gameserver = server::GameServer::new(addr); gameserver.run().unwrap(); } diff --git a/game_server/src/server.rs b/game_server/src/server.rs new file mode 100644 index 0000000..a4b1ed5 --- /dev/null +++ b/game_server/src/server.rs @@ -0,0 +1,164 @@ +use websocket::{OwnedMessage, + sync::Server, + client::sync::Client, + server::{NoTlsAcceptor, InvalidConnection, + sync::AcceptResult}}; +use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; +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"; + +pub type Token = u32; + +#[derive(Debug)] +pub enum GameServerError { + BindError(std::io::Error), + HandshakeRequestError, + InvalidProtocolError, + AcceptError(std::io::Error) +} + +pub struct GameServer { + addr: SocketAddr, + lobby: Lobby, + backend: Arc>, + clients: Arc>>, +} + +pub struct GameClient { + addr: SocketAddr, + client: Client, +} + +impl GameClient { + fn from_raw(client: Client) -> Result { + let addr = client.peer_addr().map_err(|_| ())?; + info!("got a client connection from: {}", addr); + Ok(GameClient { + addr, + client, + }) + } + + fn require_token(&mut self) -> Option { + let message = self.client + .recv_message() + .ok()?; + if let OwnedMessage::Text(text) = message { + text.parse().ok() + } else { + None + } + } +} + +type ClientConnection = Result; + +impl GameServer { + pub fn new(addr: T) -> Self { + let addr = addr.to_socket_addrs().unwrap().next().unwrap(); + debug!("ws address: {}", addr); + info!("create lobby"); + let lobby = Lobby::new(); + let backend = BackendConnection::new("https://kobert.dev"); + info!("got a C# backend connection"); + GameServer { + addr, + lobby, + backend: Arc::new(Mutex::new(backend)), + clients: Arc::new(Mutex::new(HashMap::new())), + } + } + + pub fn run(&self) -> Result<(), GameServerError> { + let reader = self.read_clients(); + loop { + let mut connection = reader.recv().unwrap()?; + self.add_client(connection); + } + Ok(()) + } + + fn add_client(&self, mut client: GameClient) { + let clients = Arc::clone(&self.clients); + let backend = Arc::clone(&self.backend); + std::thread::spawn(move || { + 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"); + } + }); + } + + fn read_clients(&self) -> Receiver { + let (s, r): (Sender, Receiver) + = mpsc::channel(); + let addr = self.addr; + std::thread::spawn(move || { + let result = Self::handle_requests(addr, &s).or_else(|e| s.send(Err(e))); + }); + r + } + + fn handle_requests(addr: SocketAddr, s: &Sender) -> Result<(), GameServerError> { + let server = match Server::::bind(addr) { + Ok(v) => v, + Err(e) => { + error!("websocket binding error"); + Err(GameServerError::BindError(e))? + }, + }; + info!("webserver is being launched"); + for req in server { + s.send(Ok(Self::handle_request(req)?)).unwrap(); + } + info!("webserver is being shut down"); + Ok(()) + } + + fn handle_request(req: AcceptResult) -> ClientConnection { + match req { + Ok(req) => { + if !req.protocols().contains(&PROTOCOL.to_string()) { + warn!("a client tried to connect without {} protocol", PROTOCOL); + req.reject().unwrap(); + Err(GameServerError::InvalidProtocolError) + } else { + match req.use_protocol(PROTOCOL).accept() { + Ok(client) => { + match GameClient::from_raw(client) { + Ok(client) => Ok(client), + Err(_) => { + error!("could not create a client"); + Err(GameServerError::HandshakeRequestError) + } + } + }, + Err((_, e)) => { + warn!("client handshake failed"); + Err(GameServerError::AcceptError(e)) + } + } + } + }, + Err(e) => { + warn!("invalid client request"); + Err(GameServerError::HandshakeRequestError) + } + } + } +} -- cgit v1.2.3-54-g00ecf From 2d815af3f6d062d55da2f2598ce5d506ee74cb6e Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 18:44:04 +0200 Subject: Refactor code --- game_server/src/backend_connection.rs | 10 +--------- game_server/src/main.rs | 2 -- game_server/src/server.rs | 7 +++---- 3 files changed, 4 insertions(+), 15 deletions(-) (limited to 'game_server/src/main.rs') diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index 4a12439..ed112d9 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -18,10 +18,6 @@ pub enum BackendError { BadResponse(Response), } -struct TokenResponseStruct { - -} - pub type TokenValidity = Result<(), BackendError>; pub type RequestData = Url; pub type ResponseResult = Result; @@ -59,14 +55,10 @@ impl BackendConnection { 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 mut response = self.get_response().map_err(|err| BackendError::RequestError(err))?; + let response = self.get_response().map_err(|err| BackendError::RequestError(err))?; if response.status().is_success() { Ok(()) } else if response.status() == reqwest::StatusCode::NOT_FOUND { diff --git a/game_server/src/main.rs b/game_server/src/main.rs index 4d05efe..628062e 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -8,8 +8,6 @@ mod game_logger; #[macro_use] extern crate log; -use backend_connection::BackendConnection; - fn main() { game_logger::init_logger(); diff --git a/game_server/src/server.rs b/game_server/src/server.rs index 79cd322..7a9c5b0 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -1,7 +1,7 @@ use websocket::{OwnedMessage, sync::Server, client::sync::Client, - server::{NoTlsAcceptor, InvalidConnection, + server::{NoTlsAcceptor, sync::AcceptResult}}; use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; use std::sync::{mpsc, @@ -82,10 +82,9 @@ impl GameServer { pub fn run(&self) -> Result<(), GameServerError> { let reader = self.read_clients(); loop { - let mut connection = reader.recv().unwrap()?; + let connection = reader.recv().unwrap()?; self.add_client(connection); } - Ok(()) } fn add_client(&self, mut client: GameClient) { @@ -160,7 +159,7 @@ impl GameServer { } } }, - Err(e) => { + Err(_) => { warn!("invalid client request"); Err(GameServerError::HandshakeRequestError) } -- cgit v1.2.3-54-g00ecf From 054a2bfe069ed4118d2f9fd1f01428632049057b Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Sun, 19 May 2019 22:38:25 +0200 Subject: Add a client handling system --- game_server/src/backend_connection.rs | 21 +++++++++++++--- game_server/src/group.rs | 8 +++++- game_server/src/lobby.rs | 30 ++++++++++++++++++++-- game_server/src/main.rs | 4 +-- game_server/src/scribble_group.rs | 42 +++++++++++++++++++++++++++++++ game_server/src/server.rs | 47 +++++++++++++++++++---------------- game_server/src/test_group.rs | 28 --------------------- 7 files changed, 122 insertions(+), 58 deletions(-) create mode 100644 game_server/src/scribble_group.rs delete mode 100644 game_server/src/test_group.rs (limited to 'game_server/src/main.rs') diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index ed112d9..e1844ee 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -1,7 +1,8 @@ use reqwest::{Response, Client, Url, UrlError, Error as ReqError}; use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; -use super::server::Token; +use super::server::{UserId, Token}; +use super::group::GroupId; pub struct BackendConnection { host: String, @@ -18,10 +19,17 @@ pub enum BackendError { BadResponse(Response), } -pub type TokenValidity = Result<(), BackendError>; +pub type TokenValidity = Result; pub type RequestData = Url; pub type ResponseResult = Result; +pub struct TokenResponse { + pub group_id: GroupId, + pub group_type: String, + pub group_name: String, + pub user_id: UserId, +} + impl BackendConnection { fn run_background(req_rec: Receiver, res_sender: Sender) { let client = Client::new(); @@ -60,7 +68,14 @@ impl BackendConnection { self.request(&location).map_err(|err| BackendError::UrlError(err))?; let response = self.get_response().map_err(|err| BackendError::RequestError(err))?; if response.status().is_success() { - Ok(()) + // zu Testzwecken werden noch keine JSON-Daten deserialisiert + // Dennis Server gibt ja noch nix zurück + Ok(TokenResponse { + group_id: 12, + group_type: "scribble".to_string(), + group_name: "Scribble".to_string(), + user_id: 420 + }) } else if response.status() == reqwest::StatusCode::NOT_FOUND { Err(BackendError::InvalidToken) } else if response.status().is_client_error() { diff --git a/game_server/src/group.rs b/game_server/src/group.rs index 55e4fbf..6356a14 100644 --- a/game_server/src/group.rs +++ b/game_server/src/group.rs @@ -1,8 +1,14 @@ +use super::server::{UserId, GameClient}; + pub type GroupId = u32; pub trait Group { fn id(&self) -> GroupId; + fn group_type(&self) -> String; fn name(&self) -> String; - fn run(&self); + fn run(&mut self); + + fn add_client(&mut self, id: UserId, client: GameClient); + fn get_client(&self, client_id: UserId) -> Option<&GameClient>; } diff --git a/game_server/src/lobby.rs b/game_server/src/lobby.rs index fe3bdee..d03bd45 100644 --- a/game_server/src/lobby.rs +++ b/game_server/src/lobby.rs @@ -1,23 +1,49 @@ use std::collections::HashMap; use super::group::{Group, GroupId}; +use super::scribble_group::ScribbleGroup; + +use super::server::{UserId, GameClient}; pub struct Lobby { groups: HashMap>, } impl Lobby { - pub fn new() -> Lobby { + pub fn new() -> Self { Self { groups: HashMap::new(), } } + fn generate_group(group_type: &str, id: GroupId, name: &str) -> Option> { + match group_type { + "scribble" => { + Some(Box::new(ScribbleGroup::new(id, name.to_string()))) + }, + other => None, + } + } + pub fn add_group(&mut self, group: Box) { self.groups.insert(group.id(), group); } - pub fn iter<'a>(&'a self) -> GroupIterator<'a> { + pub fn add_client(&mut self, group_type: &str, group_id: GroupId, group_name: &str, + user_id: UserId, client: GameClient) { + if !self.groups.contains_key(&group_id) { + let mut group = match Self::generate_group(group_type, group_id, group_name) { + Some(x) => x, + _ => return, + }; + group.run(); + self.groups.insert(group_id, group); + } + let group = self.groups.get_mut(&group_id).unwrap(); + group.add_client(user_id, client); + } + + pub fn iter<'b>(&'b self) -> GroupIterator<'b> { GroupIterator { groups: self.groups.values() } } } diff --git a/game_server/src/main.rs b/game_server/src/main.rs index 628062e..8ff8f97 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -1,5 +1,5 @@ mod group; -mod test_group; +mod scribble_group; mod lobby; mod server; mod backend_connection; @@ -13,7 +13,7 @@ fn main() { let addr = ("127.0.0.1", 5001); info!("create game server on {:?}", addr); - let gameserver = server::GameServer::new(addr); + let mut gameserver = server::GameServer::new(addr); gameserver.run().unwrap(); } diff --git a/game_server/src/scribble_group.rs b/game_server/src/scribble_group.rs new file mode 100644 index 0000000..c240264 --- /dev/null +++ b/game_server/src/scribble_group.rs @@ -0,0 +1,42 @@ +use super::group::{Group, GroupId}; +use super::server::{UserId, GameClient}; +use std::collections::HashMap; + +pub struct ScribbleGroup { + id: GroupId, + name: String, + clients: HashMap +} + +impl Group for ScribbleGroup { + fn id(&self) -> GroupId { + self.id + } + + fn group_type(&self) -> String { + "scribble".to_string() + } + + fn name(&self) -> String { + self.name.clone() + } + + fn run(&mut self) { + info!("a new group {}:'{}' runs now", self.id, self.name); + } + + fn add_client(&mut self, id: UserId, client: GameClient) { + debug!("user {} joined the group {}:'{}'", id, self.id, self.name); + self.clients.insert(id, client); + } + + fn get_client(&self, client_id: UserId) -> Option<&GameClient> { + self.clients.get(&client_id) + } +} + +impl ScribbleGroup { + pub fn new(id: GroupId, name: String) -> Self { + Self { id, name, clients: HashMap::new() } + } +} diff --git a/game_server/src/server.rs b/game_server/src/server.rs index 7a9c5b0..c87594b 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -14,6 +14,7 @@ use super::backend_connection::BackendConnection; const PROTOCOL: &str = "tuesday"; pub type Token = u32; +pub type UserId = u32; #[derive(Debug)] pub enum GameServerError { @@ -26,8 +27,7 @@ pub enum GameServerError { pub struct GameServer { addr: SocketAddr, lobby: Lobby, - backend: Arc>, - clients: Arc>>, + backend: BackendConnection, } pub struct GameClient { @@ -73,13 +73,12 @@ impl GameServer { info!("got a C# backend connection"); GameServer { addr, - lobby, - backend: Arc::new(Mutex::new(backend)), - clients: Arc::new(Mutex::new(HashMap::new())), + lobby: lobby, + backend: backend, } } - pub fn run(&self) -> Result<(), GameServerError> { + pub fn run(&mut self) -> Result<(), GameServerError> { let reader = self.read_clients(); loop { let connection = reader.recv().unwrap()?; @@ -87,25 +86,29 @@ 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 || { - let token = client.require_token(); - if let Some(token) = token { - let locked_backend = backend.lock().unwrap(); - let result = locked_backend.validate_token(&token); - if let Err(err) = result { - warn!("client's token {} is not valid: '{:?}'", token, err); - } else { + fn add_client(&mut self, mut client: GameClient) { + let token = client.require_token(); + if let Some(token) = token { + let result = self.backend.validate_token(&token); + match result { + Err(err) => warn!("client's token {} is not valid: '{:?}'", + token, err), + Ok(result) => { debug!("client validation was successfull"); - debug!("add client: ({}, {})", token, client.host_name()); - clients.lock().unwrap().insert(token, client); + let user_id = result.user_id; + let group_id = result.group_id; + let group_type = result.group_type; + let group_name = result.group_name; + debug!("add client: (id:{}, token:{}, host:{}) to \"{}\"", + user_id, token, client.host_name(), group_name); + //clients.lock().unwrap().insert(token, client); + self.lobby.add_client(&group_type, group_id, + &group_name, user_id, client); } - } else { - warn!("client sent invalid token"); } - }); + } else { + warn!("client sent invalid token"); + } } fn read_clients(&self) -> Receiver { diff --git a/game_server/src/test_group.rs b/game_server/src/test_group.rs deleted file mode 100644 index bd570e3..0000000 --- a/game_server/src/test_group.rs +++ /dev/null @@ -1,28 +0,0 @@ -use super::group::{Group, GroupId}; - -pub struct TestGroup { - id: GroupId, - name: String, -} - -impl Group for TestGroup { - fn id(&self) -> GroupId { - self.id - } - - fn name(&self) -> String { - self.name.clone() - } - - fn run(&self) { - let id = self.id; - let name = self.name.to_owned(); - std::thread::spawn(move || /*loop { println!("> group nr.{} wishes you: '{}'", id, name) }*/()); - } -} - -impl TestGroup { - pub fn new(id: GroupId, name: String) -> Self { - TestGroup { id, name } - } -} -- cgit v1.2.3-54-g00ecf From c7bc91ecd6c32afab52c5e45b569e3945bdd1056 Mon Sep 17 00:00:00 2001 From: natrixaeria Date: Mon, 20 May 2019 18:27:26 +0200 Subject: Broadcast all text packets around clients --- game_server/src/backend_connection.rs | 7 +++++-- game_server/src/group.rs | 1 - game_server/src/main.rs | 2 +- game_server/src/scribble_group.rs | 29 +++++++++++++++++++++-------- game_server/src/server.rs | 15 ++++++++++++--- game_server/src/ws_test.html | 7 ++++++- 6 files changed, 45 insertions(+), 16 deletions(-) (limited to 'game_server/src/main.rs') diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs index e1844ee..d32c58e 100644 --- a/game_server/src/backend_connection.rs +++ b/game_server/src/backend_connection.rs @@ -8,6 +8,7 @@ pub struct BackendConnection { host: String, req_sender: Sender, res_rec: Receiver, + max_uid: u32, } #[derive(Debug)] @@ -52,6 +53,7 @@ impl BackendConnection { host: host.to_string(), req_sender, res_rec, + max_uid: 420, } } @@ -63,18 +65,19 @@ impl BackendConnection { self.res_rec.recv().unwrap() } - pub fn validate_token(&self, token: &Token) -> TokenValidity { + pub fn validate_token(&mut 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().map_err(|err| BackendError::RequestError(err))?; if response.status().is_success() { // zu Testzwecken werden noch keine JSON-Daten deserialisiert // Dennis Server gibt ja noch nix zurück + self.max_uid += 1; Ok(TokenResponse { group_id: 12, group_type: "scribble".to_string(), group_name: "Scribble".to_string(), - user_id: 420 + user_id: self.max_uid - 1, }) } else if response.status() == reqwest::StatusCode::NOT_FOUND { Err(BackendError::InvalidToken) diff --git a/game_server/src/group.rs b/game_server/src/group.rs index 6356a14..fcda12a 100644 --- a/game_server/src/group.rs +++ b/game_server/src/group.rs @@ -10,5 +10,4 @@ pub trait Group { fn run(&mut self); fn add_client(&mut self, id: UserId, client: GameClient); - fn get_client(&self, client_id: UserId) -> Option<&GameClient>; } diff --git a/game_server/src/main.rs b/game_server/src/main.rs index 8ff8f97..ab73a97 100644 --- a/game_server/src/main.rs +++ b/game_server/src/main.rs @@ -11,7 +11,7 @@ mod game_logger; fn main() { game_logger::init_logger(); - let addr = ("127.0.0.1", 5001); + let addr = ("0.0.0.0", 5001); info!("create game server on {:?}", addr); let mut gameserver = server::GameServer::new(addr); gameserver.run().unwrap(); diff --git a/game_server/src/scribble_group.rs b/game_server/src/scribble_group.rs index c240264..e68c6df 100644 --- a/game_server/src/scribble_group.rs +++ b/game_server/src/scribble_group.rs @@ -1,11 +1,13 @@ use super::group::{Group, GroupId}; -use super::server::{UserId, GameClient}; +use super::server::{UserId, GameClient, + ClientSender, ClientReceiver}; use std::collections::HashMap; +use std::sync::{Arc, Mutex}; pub struct ScribbleGroup { id: GroupId, name: String, - clients: HashMap + senders: Arc>> } impl Group for ScribbleGroup { @@ -27,16 +29,27 @@ impl Group for ScribbleGroup { fn add_client(&mut self, id: UserId, client: GameClient) { debug!("user {} joined the group {}:'{}'", id, self.id, self.name); - self.clients.insert(id, client); - } - - fn get_client(&self, client_id: UserId) -> Option<&GameClient> { - self.clients.get(&client_id) + let (sen, mut rec) = client.split(); + self.senders.lock().unwrap().insert(id, sen); + let senders_mutex = self.senders.clone(); + let self_uid = id; + std::thread::spawn(move || { + loop { + let message = rec.recv_message().unwrap(); + info!("got message: '{:?}'", message); + let mut senders = senders_mutex.lock().unwrap(); + for (uid, sender) in senders.iter_mut() { + if self_uid != *uid { + sender.send_message(&message); + } + } + } + }); } } impl ScribbleGroup { pub fn new(id: GroupId, name: String) -> Self { - Self { id, name, clients: HashMap::new() } + Self { id, name, senders: Arc::new(Mutex::new(HashMap::new())) } } } diff --git a/game_server/src/server.rs b/game_server/src/server.rs index c87594b..6294e2c 100644 --- a/game_server/src/server.rs +++ b/game_server/src/server.rs @@ -1,16 +1,20 @@ use websocket::{OwnedMessage, + stream::sync::Splittable, sync::Server, client::sync::Client, server::{NoTlsAcceptor, - sync::AcceptResult}}; + sync::AcceptResult}, + receiver, sender}; use std::net::{SocketAddr, ToSocketAddrs, TcpStream}; use std::sync::{mpsc, - mpsc::{Sender, Receiver}, - Arc, Mutex}; + mpsc::{Sender, Receiver}}; use std::collections::HashMap; use super::lobby::Lobby; use super::backend_connection::BackendConnection; +pub type ClientReceiver = receiver::Reader<::Reader>; +pub type ClientSender = sender::Writer<::Writer>; + const PROTOCOL: &str = "tuesday"; pub type Token = u32; @@ -59,6 +63,11 @@ impl GameClient { fn host_name(&self) -> SocketAddr { self.addr } + + pub fn split(self) -> (ClientSender, ClientReceiver) { + let (mut rec, mut sen) = self.client.split().unwrap(); + (sen, rec) + } } type ClientConnection = Result; diff --git a/game_server/src/ws_test.html b/game_server/src/ws_test.html index f802327..ee60b65 100644 --- a/game_server/src/ws_test.html +++ b/game_server/src/ws_test.html @@ -12,6 +12,7 @@
connected


Server address: + Message