summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornatrixaeria <janng@gmx.de>2019-05-18 05:27:06 +0200
committernatrixaeria <janng@gmx.de>2019-05-18 05:27:06 +0200
commit70f46161fe0c9819d463cf612d60d4c03faabe7e (patch)
treea5c75f2b72b1608b15af4fe9eea11d252e2acbbc
parentbc74dde4dd7cf40216de4f0aae9a1b9ddf5e044b (diff)
Add threading and possibility to connect to socket
-rw-r--r--game_server/Cargo.toml1
-rw-r--r--game_server/src/gameserver.rs148
-rw-r--r--game_server/src/main.rs17
-rw-r--r--game_server/src/ws_test.html5
4 files changed, 131 insertions, 40 deletions
diff --git a/game_server/Cargo.toml b/game_server/Cargo.toml
index baf27fa..97c0e77 100644
--- a/game_server/Cargo.toml
+++ b/game_server/Cargo.toml
@@ -10,3 +10,4 @@ log = "0.4"
pretty_env_logger = "0.3"
reqwest = "0.9"
websocket = "0.22"
+hyper = "0.10"
diff --git a/game_server/src/gameserver.rs b/game_server/src/gameserver.rs
index 6bc3e07..377654e 100644
--- a/game_server/src/gameserver.rs
+++ b/game_server/src/gameserver.rs
@@ -1,44 +1,146 @@
-use websocket::{OwnedMessage, sync::Server, server::NoTlsAcceptor};
-use std::net::{SocketAddr, ToSocketAddrs};
+use websocket::{OwnedMessage,
+ sync::Server,
+ client::sync::Client,
+ server::{NoTlsAcceptor, InvalidConnection,
+ sync::AcceptResult}};
+use std::net::{SocketAddr, ToSocketAddrs, TcpStream};
use std::sync::mpsc;
use std::sync::mpsc::{Sender, Receiver};
+use super::lobby::Lobby;
+use super::backend_connection::BackendConnection;
+
+const PROTOCOL: &str = "tuesday";
+
+type Token = u32;
#[derive(Debug)]
pub enum GameServerError {
BindError(std::io::Error),
+ HandshakeRequestError,
+ InvalidProtocolError,
+ AcceptError(std::io::Error)
}
-type ClientConnection = Result<(), GameServerError>;
-
pub struct GameServer {
addr: SocketAddr,
- rec: Receiver<ClientConnection>,
+ lobby: Lobby,
+ backend: BackendConnection,
+}
+
+pub struct GameClient {
+ addr: SocketAddr,
+ client: Client<TcpStream>,
+}
+
+impl GameClient {
+ fn from_raw(client: Client<TcpStream>) -> Result<Self, ()> {
+ let addr = client.peer_addr().map_err(|_| ())?;
+ info!("got a client connection from: {}", addr);
+ Ok(GameClient {
+ addr,
+ client,
+ })
+ }
+
+ fn require_token(&mut self) -> Option<Token> {
+ let message = self.client
+ .recv_message()
+ .ok()?;
+ if let OwnedMessage::Text(text) = message {
+ text.parse::<Token>().ok()
+ } else {
+ None
+ }
+ }
}
+type ClientConnection = Result<GameClient, GameServerError>;
+
impl GameServer {
pub fn new<T: ToSocketAddrs>(addr: T) -> Self {
- let (s, r): (Sender<ClientConnection>, Receiver<ClientConnection>)
- = mpsc::channel();
let addr = addr.to_socket_addrs().unwrap().next().unwrap();
debug!("ws address: {}", addr);
- std::thread::spawn(move || {
- let server = match Server::<NoTlsAcceptor>::bind(addr) {
- Ok(v) => v,
- Err(e) => {
- s.send(Err(GameServerError::BindError(e))).unwrap();
- return;
- },
- };
- info!("webserver is being launched");
- for req in server {
- //println!("{:?}", req);
- println!("gotcha");
- }
- info!("webserver is being shut down");
- });
+ info!("create lobby");
+ let lobby = Lobby::new();
+ let backend = BackendConnection::new("https://kobert.dev");
+ info!("got a C# backend connection");
GameServer {
addr,
- rec: r,
+ lobby,
+ backend,
+ }
+ }
+
+ 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) {
+ std::thread::spawn(move || {
+ println!("Token: {:?}", client.require_token());
+ });
+ }
+
+ fn read_clients(&self) -> Receiver<ClientConnection> {
+ let (s, r): (Sender<ClientConnection>, Receiver<ClientConnection>)
+ = 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<ClientConnection>) -> Result<(), GameServerError> {
+ let server = match Server::<NoTlsAcceptor>::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<TcpStream>) -> 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 2d261d8..d8a7b53 100644
--- a/game_server/src/main.rs
+++ b/game_server/src/main.rs
@@ -7,27 +7,14 @@ mod backend_connection;
#[macro_use] extern crate log;
use pretty_env_logger;
-use lobby::Lobby;
use backend_connection::BackendConnection;
fn main() {
pretty_env_logger::init();
- info!("create lobby");
- let mut lobby = Lobby::new();
- let addr = ("127.0.0.1", 5001);
+ let addr = ("0.0.0.0", 5001);
info!("create game server on {:?}", addr);
let gameserver = gameserver::GameServer::new(addr);
+ gameserver.run().unwrap();
- for group in lobby.iter() {
- group.run()
- }
-
- let mut backend = BackendConnection::new("https://kobert.dev");
- loop {
- std::thread::sleep(std::time::Duration::from_millis(1000));
-
- //backend.request("/api/lobby/tokens/1230").unwrap();
- //println!("{:?}", backend.get_response());
- }
}
diff --git a/game_server/src/ws_test.html b/game_server/src/ws_test.html
index 29d4d50..ea259b7 100644
--- a/game_server/src/ws_test.html
+++ b/game_server/src/ws_test.html
@@ -22,10 +22,11 @@ function get_addr() {
function test_connection() {
let a = 'ws://' + get_addr();
add_text('create a new connection at "' + a + '"');
- const ws = new WebSocket(a);
+ const ws = new WebSocket(a, 'tuesday');
ws.addEventListener('open', function (event) {
add_text('connection established');
toggle_connected(true);
+ ws.send('1230123');
});
ws.addEventListener('error', function (event) {
add_text('ws error occured: "' + event + '"');
@@ -36,7 +37,7 @@ function test_connection() {
toggle_connected(false);
});
ws.addEventListener('message', function (event) {
- add_text('got ws message: ' + event);
+ add_text('got ws message: ' + event.data);
});
}