From c45a9524b307c264e69aa017fcf370d71ea799da Mon Sep 17 00:00:00 2001
From: natrixaeria
Date: Sun, 19 May 2019 15:39:48 +0200
Subject: Push new clients to a Map
---
game_server/src/gameserver.rs | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/game_server/src/gameserver.rs b/game_server/src/gameserver.rs
index 9334a27..6f6dead 100644
--- a/game_server/src/gameserver.rs
+++ b/game_server/src/gameserver.rs
@@ -4,8 +4,10 @@ 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;
@@ -25,6 +27,7 @@ pub struct GameServer {
addr: SocketAddr,
lobby: Lobby,
backend: BackendConnection,
+ clients: Arc>>,
}
pub struct GameClient {
@@ -47,7 +50,7 @@ impl GameClient {
.recv_message()
.ok()?;
if let OwnedMessage::Text(text) = message {
- text.parse::().ok()
+ text.parse().ok()
} else {
None
}
@@ -68,6 +71,7 @@ impl GameServer {
addr,
lobby,
backend,
+ clients: Arc::new(Mutex::new(HashMap::new())),
}
}
@@ -81,9 +85,15 @@ impl GameServer {
}
fn add_client(&self, mut client: GameClient) {
+ let clients = Arc::clone(&self.clients);
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);
+ clients.lock().unwrap().insert(token, client);
+ } else {
+ warn!("Client sent invalid token");
+ }
});
}
--
cgit v1.2.3-54-g00ecf
From 91a1321f0ae1a02df9c3d1a8f890d84a94953a61 Mon Sep 17 00:00:00 2001
From: natrixaeria
Date: Sun, 19 May 2019 17:09:56 +0200
Subject: Validate tokens and then push client
---
game_server/src/backend_connection.rs | 57 +++++++++++++++++++++++++++++------
game_server/src/gameserver.rs | 17 ++++++++---
2 files changed, 59 insertions(+), 15 deletions(-)
diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs
index 9307c4a..6d3537a 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>
+ req_sender: Sender,
+ res_rec: Receiver,
}
+#[derive(Debug)]
+pub enum BackendError {
+ UrlError(UrlError),
+ RequestError(ReqError),
+ InvalidTokenFormat,
+ InvalidToken,
+}
+
+pub type TokenValidity = Result<(), BackendError>;
+pub type RequestData = Url;
+pub type ResponseResult = Result;
+
impl BackendConnection {
+ fn run_background(req_rec: Receiver, res_sender: Sender) {
+ 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);
+ }
+ }
+
pub fn new(host: &str) -> Self {
+ let (req_sender, req_rec): (Sender, Receiver)
+ = mpsc::channel();
+ let (res_sender, res_rec): (Sender, Receiver)
+ = 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> {
- &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/gameserver.rs b/game_server/src/gameserver.rs
index 6f6dead..a4b1ed5 100644
--- a/game_server/src/gameserver.rs
+++ b/game_server/src/gameserver.rs
@@ -13,7 +13,7 @@ use super::backend_connection::BackendConnection;
const PROTOCOL: &str = "tuesday";
-type Token = u32;
+pub type Token = u32;
#[derive(Debug)]
pub enum GameServerError {
@@ -26,7 +26,7 @@ pub enum GameServerError {
pub struct GameServer {
addr: SocketAddr,
lobby: Lobby,
- backend: BackendConnection,
+ backend: Arc>,
clients: Arc>>,
}
@@ -70,7 +70,7 @@ impl GameServer {
GameServer {
addr,
lobby,
- backend,
+ backend: Arc::new(Mutex::new(backend)),
clients: Arc::new(Mutex::new(HashMap::new())),
}
}
@@ -86,13 +86,20 @@ 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 {
println!("Token: {}", token);
- clients.lock().unwrap().insert(token, client);
+ 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");
+ warn!("client sent invalid token");
}
});
}
--
cgit v1.2.3-54-g00ecf
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/Cargo.toml | 3 ++-
game_server/src/backend_connection.rs | 2 +-
game_server/src/game_logger.rs | 29 +++++++++++++++++++++++++++++
game_server/src/main.rs | 5 +++--
4 files changed, 35 insertions(+), 4 deletions(-)
create mode 100644 game_server/src/game_logger.rs
diff --git a/game_server/Cargo.toml b/game_server/Cargo.toml
index 97c0e77..bc14942 100644
--- a/game_server/Cargo.toml
+++ b/game_server/Cargo.toml
@@ -7,7 +7,8 @@ description = "A general game server for connections to web clients. Currently (
[dependencies]
log = "0.4"
-pretty_env_logger = "0.3"
+fern = "0.5.8"
+colored = "1.8"
reqwest = "0.9"
websocket = "0.22"
hyper = "0.10"
diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs
index 6d3537a..11642f2 100644
--- a/game_server/src/backend_connection.rs
+++ b/game_server/src/backend_connection.rs
@@ -29,7 +29,7 @@ impl BackendConnection {
let location = request_data;
let request = client.get(location);
let response = request.send();
- res_sender.send(response);
+ res_sender.send(response).unwrap();
}
}
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/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 c3bb858bb54dc8c64bbd48054c2c58dc0073f09c Mon Sep 17 00:00:00 2001
From: natrixaeria
Date: Sun, 19 May 2019 17:39:50 +0200
Subject: Remove build script
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Copilation works now as usual with ´cargo run´ / ´cargo build´
---
game_server/build.sh | 21 ---------------
game_server/err | 73 ---------------------------------------------------
game_server/rbuild.sh | 2 --
3 files changed, 96 deletions(-)
delete mode 100755 game_server/build.sh
delete mode 100644 game_server/err
delete mode 100644 game_server/rbuild.sh
diff --git a/game_server/build.sh b/game_server/build.sh
deleted file mode 100755
index 1eb61a1..0000000
--- a/game_server/build.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env sh
-
-case $1 in
- ("")
- if rustup run stable cargo --color always build; then
- echo build success!
- RUST_LOG=debug target/debug/game-server
- else
- echo build failed!
- fi
- ;;
- -r)
- sh build.sh &> err && cat err | tac
- ;;
- -c)
- rustup run stable cargo clean
- ;;
- *)
- echo invalid argument
- ;;
-esac
diff --git a/game_server/err b/game_server/err
deleted file mode 100644
index 6ca8a6f..0000000
--- a/game_server/err
+++ /dev/null
@@ -1,73 +0,0 @@
-[0m[0m[1m[32m Compiling[0m game-server v0.1.0 (/home/jan/projects/DiscoBot/game_server)
-[0m[1m[38;5;9merror[E0277][0m[0m[1m: the trait bound `(): futures::future::Future` is not satisfied[0m
-[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:32:24[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m[1m[38;5;12m32[0m[0m [0m[0m[1m[38;5;12m| [0m[0m hyper::rt::run(hyper::rt::lazy(|| {[0m
-[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^^^^^^^^^^^^^[0m[0m [0m[0m[1m[38;5;9mthe trait `futures::future::Future` is not implemented for `()`[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required because of the requirements on the impl of `futures::future::IntoFuture` for `()`[0m
-[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required by `futures::future::lazy::lazy`[0m
-
-[0m[1m[38;5;9merror[E0599][0m[0m[1m: no method named `wait` found for type `std::result::Result, [closure@src/backend_connection.rs:55:38: 55:73]>, http::uri::InvalidUri>` in the current scope[0m
-[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:56:24[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m[1m[38;5;12m56[0m[0m [0m[0m[1m[38;5;12m| [0m[0m }).wait();[0m
-[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^^[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: the method `wait` exists but the following trait bounds were not satisfied:[0m
-[0m `&mut std::result::Result, [closure@src/backend_connection.rs:55:38: 55:73]>, http::uri::InvalidUri> : futures::future::Future`[0m
-
-[0m[1m[38;5;9merror[E0308][0m[0m[1m: mismatched types[0m
-[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:58:17[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m[1m[38;5;12m58[0m[0m [0m[0m[1m[38;5;12m| [0m[0m res[0m
-[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^[0m[0m [0m[0m[1m[38;5;9mexpected (), found enum `std::result::Result`[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: expected type `[0m[0m[1m()[0m[0m`[0m
-[0m found type `[0m[0m[1mstd::result::Result, http::uri::InvalidUri>[0m[0m`[0m
-
-[0m[1m[38;5;9merror[E0277][0m[0m[1m: the trait bound `(): futures::future::Future` is not satisfied[0m
-[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:32:24[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m[1m[38;5;12m32[0m[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m hyper::rt::run(hyper::rt::lazy(|| {[0m
-[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m________________________^[0m
-[0m[1m[38;5;12m33[0m[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|[0m[0m [0m[0m let client = hyper::Client::builder()[0m
-[0m[1m[38;5;12m34[0m[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|[0m[0m [0m[0m .build::<_, hyper::Body>([0m
-[0m[1m[38;5;12m35[0m[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|[0m[0m [0m[0m HttpsConnector::new(4).unwrap()[0m
-[0m[1m[38;5;12m...[0m[0m [0m[0m[1m[38;5;9m|[0m
-[0m[1m[38;5;12m59[0m[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|[0m[0m [0m[0m }[0m
-[0m[1m[38;5;12m60[0m[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|[0m[0m [0m[0m }));[0m
-[0m [0m[0m[1m[38;5;12m| [0m[0m[1m[38;5;9m|__________^[0m[0m [0m[0m[1m[38;5;9mthe trait `futures::future::Future` is not implemented for `()`[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required because of the requirements on the impl of `futures::future::IntoFuture` for `()`[0m
-[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required by `futures::future::lazy::Lazy`[0m
-
-[0m[1m[38;5;9merror[E0277][0m[0m[1m: the trait bound `(): futures::future::Future` is not satisfied[0m
-[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:32:9[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m[1m[38;5;12m32[0m[0m [0m[0m[1m[38;5;12m| [0m[0m hyper::rt::run(hyper::rt::lazy(|| {[0m
-[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^^^^^^^^^^^^[0m[0m [0m[0m[1m[38;5;9mthe trait `futures::future::Future` is not implemented for `()`[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required because of the requirements on the impl of `futures::future::IntoFuture` for `()`[0m
-[0m [0m[0m[1m[38;5;12m= [0m[0m[1mnote[0m[0m: required by `hyper::rt::run`[0m
-
-[0m[1m[38;5;9merror[E0063][0m[0m[1m: missing field `res_receiver` in initializer of `backend_connection::BackendConnection`[0m
-[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:62:9[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m[1m[38;5;12m62[0m[0m [0m[0m[1m[38;5;12m| [0m[0m BackendConnection {[0m
-[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^^^^^^^^^^^^^^^[0m[0m [0m[0m[1m[38;5;9mmissing `res_receiver`[0m
-
-[0m[1m[38;5;9merror[E0609][0m[0m[1m: no field `request_sender` on type `&backend_connection::BackendConnection`[0m
-[0m [0m[0m[1m[38;5;12m--> [0m[0msrc/backend_connection.rs:69:14[0m
-[0m [0m[0m[1m[38;5;12m|[0m
-[0m[1m[38;5;12m69[0m[0m [0m[0m[1m[38;5;12m| [0m[0m self.request_sender.send([0m
-[0m [0m[0m[1m[38;5;12m| [0m[0m [0m[0m[1m[38;5;9m^^^^^^^^^^^^^^[0m
-
-[0m[1m[38;5;9merror[0m[0m[1m: aborting due to 7 previous errors[0m
-
-[0m[1mSome errors have detailed explanations: E0063, E0277, E0308, E0599, E0609.[0m
-[0m[1mFor more information about an error, try `rustc --explain E0063`.[0m
-[0m[0m[1m[31merror:[0m Could not compile `game-server`.
-
-To learn more, run the command again with --verbose.
-build failed!
diff --git a/game_server/rbuild.sh b/game_server/rbuild.sh
deleted file mode 100644
index 22b10b5..0000000
--- a/game_server/rbuild.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-sh build.sh &> err && cat err | tac
--
cgit v1.2.3-54-g00ecf
From fbed43a319dae36d961f8d6a073c32d84c90c75f Mon Sep 17 00:00:00 2001
From: natrixaeria
Date: Sun, 19 May 2019 17:43:34 +0200
Subject: Disable logging for tokio-core and reqwest
---
game_server/src/game_logger.rs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/game_server/src/game_logger.rs b/game_server/src/game_logger.rs
index e49ebe8..c51bfc5 100644
--- a/game_server/src/game_logger.rs
+++ b/game_server/src/game_logger.rs
@@ -23,7 +23,8 @@ pub fn init_logger() {
})
.level(log::LevelFilter::Debug)
.level_for("hyper", log::LevelFilter::Off)
- .level_for("tokio-reactor", log::LevelFilter::Off)
+ .level_for("tokio_reactor", log::LevelFilter::Off)
+ .level_for("reqwest", log::LevelFilter::Off)
.chain(std::io::stdout())
.apply().unwrap();
}
--
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
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 36df226f113151fe3c18831a082fea64ba8a0c03 Mon Sep 17 00:00:00 2001
From: natrixaeria
Date: Sun, 19 May 2019 18:25:29 +0200
Subject: Validate tokens successfully
---
game_server/src/backend_connection.rs | 18 +++++++++++++++---
game_server/src/server.rs | 9 +++++++--
game_server/src/ws_test.html | 3 ++-
3 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/game_server/src/backend_connection.rs b/game_server/src/backend_connection.rs
index fa41791..4a12439 100644
--- a/game_server/src/backend_connection.rs
+++ b/game_server/src/backend_connection.rs
@@ -15,6 +15,11 @@ pub enum BackendError {
RequestError(ReqError),
InvalidTokenFormat,
InvalidToken,
+ BadResponse(Response),
+}
+
+struct TokenResponseStruct {
+
}
pub type TokenValidity = Result<(), BackendError>;
@@ -61,8 +66,15 @@ impl BackendConnection {
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(())
+ let mut response = self.get_response().map_err(|err| BackendError::RequestError(err))?;
+ if response.status().is_success() {
+ Ok(())
+ } else if response.status() == reqwest::StatusCode::NOT_FOUND {
+ Err(BackendError::InvalidToken)
+ } else if response.status().is_client_error() {
+ Err(BackendError::InvalidTokenFormat)
+ } else {
+ Err(BackendError::BadResponse(response))
+ }
}
}
diff --git a/game_server/src/server.rs b/game_server/src/server.rs
index a4b1ed5..79cd322 100644
--- a/game_server/src/server.rs
+++ b/game_server/src/server.rs
@@ -55,6 +55,10 @@ impl GameClient {
None
}
}
+
+ fn host_name(&self) -> SocketAddr {
+ self.addr
+ }
}
type ClientConnection = Result;
@@ -90,12 +94,13 @@ impl GameServer {
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);
+ warn!("client's token {} is not valid: '{:?}'", token, err);
} else {
+ debug!("client validation was successfull");
+ debug!("add client: ({}, {})", token, client.host_name());
clients.lock().unwrap().insert(token, client);
}
} else {
diff --git a/game_server/src/ws_test.html b/game_server/src/ws_test.html
index ea259b7..f802327 100644
--- a/game_server/src/ws_test.html
+++ b/game_server/src/ws_test.html
@@ -26,7 +26,8 @@ function test_connection() {
ws.addEventListener('open', function (event) {
add_text('connection established');
toggle_connected(true);
- ws.send('1230123');
+ // send token
+ ws.send('42');
});
ws.addEventListener('error', function (event) {
add_text('ws error occured: "' + event + '"');
--
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(-)
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
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(-)
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
+
+