Browse Source

Cleanup & add better error handling

new_protocol
ThePerkinrex 5 years ago
parent
commit
434bfab134
No known key found for this signature in database GPG Key ID: FD81DE6D75E20917
  1. 155
      server/src/server.rs
  2. 5
      server/src/server/socket_manager.rs

155
server/src/server.rs

@ -1,19 +1,28 @@
// use tonic::transport::Server; // use tonic::transport::Server;
use anyhow::Result; use anyhow::Result;
use log::info; use log::warn;
use tokio::{ use tokio::{
io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, io::{AsyncReadExt, BufReader},
net::{tcp::OwnedWriteHalf, TcpListener}, net::TcpListener,
sync::RwLock, sync::RwLock,
}; };
use uuid::Uuid; use uuid::Uuid;
use std::{collections::HashMap, net::SocketAddr, sync::Arc}; use std::{collections::HashMap, io::ErrorKind, net::SocketAddr, sync::Arc};
use crate::{db, games::RunningGame, server::{connection::{ use crate::{
db,
games::RunningGame,
server::{
connection::{
connect, create_lobby, disconnect, get_public_lobbies, join_lobby_with_code, name, connect, create_lobby, disconnect, get_public_lobbies, join_lobby_with_code, name,
}, game::{on_click, get_card_image}, lobby::{leave, ready, users, vote}}, server_properties::ServerProperties}; },
game::{get_card_image, on_click},
lobby::{leave, ready, users, vote},
},
server_properties::ServerProperties,
};
use prost::Message; use prost::Message;
@ -23,8 +32,8 @@ mod connection;
mod game; mod game;
mod lobby; mod lobby;
mod protos; mod protos;
mod votes;
mod socket_manager; mod socket_manager;
mod votes;
// use connection::{ConnectionServer, ConnectionService}; // use connection::{ConnectionServer, ConnectionService};
// use game::{GameServer, GameService}; // use game::{GameServer, GameService};
@ -119,19 +128,57 @@ pub async fn serve(
let socket_manager = socket_manager.clone(); let socket_manager = socket_manager.clone();
tokio::spawn(async move { tokio::spawn(async move {
loop { loop {
let length = reader let length = match reader.read_u32_le().await {
.read_u32_le() Err(e) => match e.kind() {
.await ErrorKind::UnexpectedEof => {
if let Some(user) = service_data.user_id.0 {
warn!(
"Unexpected EOF for {} from {}, disconnecting",
user, service_data.addr
);
} else {
warn!("Unexpected EOF from {}, disconnecting", service_data.addr);
}
break;
}
_ => Err(e),
},
x => x,
}
.expect("Unexpected inability to read the length of a packet (U32 LE)"); .expect("Unexpected inability to read the length of a packet (U32 LE)");
let mut data = vec![0; length as usize]; let mut data = vec![0; length as usize];
reader match reader.read_exact(&mut data).await {
.read_exact(&mut data) Err(e) => match e.kind() {
.await ErrorKind::UnexpectedEof => {
if let Some(user) = service_data.user_id.0 {
warn!(
"Unexpected EOF for {} from {}, disconnecting",
user, service_data.addr
);
} else {
warn!("Unexpected EOF from {}, disconnecting", service_data.addr);
}
break;
}
_ => Err(e),
},
x => x,
}
.expect("Error reading packet"); .expect("Error reading packet");
let packet = protos::protocol::ClientServerPacket::decode(data.as_slice()) let packet = match protos::protocol::ClientServerPacket::decode(data.as_slice()) {
.expect("Error decoding the data") Err(e) => {
.data warn!("Error decoding the packet, skipping ({})", e);
.expect("Unexpected data in packet recieved"); continue;
}
Ok(d) => d,
};
let packet = match packet.data {
Some(packet) => packet,
None => {
warn!("Unexpected data in packet ({:?}), skipping", packet);
continue;
}
};
use protos::protocol::client_server_packet::Data; use protos::protocol::client_server_packet::Data;
match packet { match packet {
@ -139,36 +186,72 @@ pub async fn serve(
Data::QueryName(()) => name(&mut service_data, &socket_manager) Data::QueryName(()) => name(&mut service_data, &socket_manager)
.await .await
.expect("Error handling name query"), .expect("Error handling name query"),
Data::Connect(name) => connect(&mut service_data, writer.take().ok_or(anyhow::anyhow!("Connect shouldn't be called more than once")).unwrap(), &socket_manager, name) Data::Connect(name) => connect(
&mut service_data,
writer
.take()
.ok_or(anyhow::anyhow!(
"Connect shouldn't be called more than once"
))
.unwrap(),
&socket_manager,
name,
)
.await .await
.expect("Error handling connect"), .expect("Error handling connect"),
Data::Disconnect(()) => disconnect(&mut service_data) Data::Disconnect(()) => {
.await break;
.expect("Error handling disconnect"), }
Data::JoinLobby(code) => join_lobby_with_code(&mut service_data, code) Data::JoinLobby(code) => join_lobby_with_code(&mut service_data, code)
.await .await
.expect("Error handling join with code"), .expect("Error handling join with code"),
Data::CreateLobby(config) => create_lobby(&mut service_data, &socket_manager, config) Data::CreateLobby(config) => {
create_lobby(&mut service_data, &socket_manager, config)
.await .await
.expect("Error handling create lobby"), .expect("Error handling create lobby")
}
Data::QueryGames(()) => connection::games(&mut service_data, &socket_manager) Data::QueryGames(()) => connection::games(&mut service_data, &socket_manager)
.await .await
.expect("Error handling games query"), .expect("Error handling games query"),
Data::QueryPublicLobbies(()) => get_public_lobbies(&mut service_data, &socket_manager) Data::QueryPublicLobbies(()) => {
get_public_lobbies(&mut service_data, &socket_manager)
.await .await
.expect("Error handling public lobbies query"), .expect("Error handling public lobbies query")
}
// LOBBY // LOBBY
Data::QueryUsers(()) => users(&mut service_data, &socket_manager).await.expect("Error handling users query"), Data::QueryUsers(()) => users(&mut service_data, &socket_manager)
Data::Vote(v) => vote(&mut service_data, &socket_manager, v).await.expect("Error handling vote"), .await
Data::Ready(()) => ready(&mut service_data, &socket_manager).await.expect("Error handling ready"), .expect("Error handling users query"),
Data::Leave(()) => leave(&mut service_data, &socket_manager).await.expect("Error handling leave"), Data::Vote(v) => vote(&mut service_data, &socket_manager, v)
.await
.expect("Error handling vote"),
Data::Ready(()) => ready(&mut service_data, &socket_manager)
.await
.expect("Error handling ready"),
Data::Leave(()) => leave(&mut service_data, &socket_manager)
.await
.expect("Error handling leave"),
// GAME // GAME
Data::QueryCardImage(card_kind) => get_card_image(&mut service_data, &socket_manager, card_kind).await.expect("Error handling card image query"), Data::QueryCardImage(card_kind) => {
Data::CallOnClick(card_id) => on_click(&mut service_data, &socket_manager, card_id).await.expect("Error handling on_click call") get_card_image(&mut service_data, &socket_manager, card_kind)
.await
.expect("Error handling card image query")
}
Data::CallOnClick(card_id) => {
on_click(&mut service_data, &socket_manager, card_id)
.await
.expect("Error handling on_click call")
}
} }
} }
if let Some(user) = service_data.user_id.0 {
disconnect(&mut service_data)
.await
.expect("Error handling disconnect");
socket_manager.disconnect(&user).await;
}
}); });
} }
} }
@ -202,9 +285,9 @@ impl UserId {
Self(None) Self(None)
} }
pub fn new_filled(uuid: Uuid) -> Self { // pub fn new_filled(uuid: Uuid) -> Self {
Self(Some(uuid)) // Self(Some(uuid))
} // }
pub fn set(&mut self, uuid: Uuid) { pub fn set(&mut self, uuid: Uuid) {
self.0 = Some(uuid); self.0 = Some(uuid);
@ -215,6 +298,8 @@ impl UserId {
} }
pub fn get_ref(&self) -> Result<&Uuid> { pub fn get_ref(&self) -> Result<&Uuid> {
self.0.as_ref().ok_or(anyhow::anyhow!("User should have connected")) self.0
.as_ref()
.ok_or(anyhow::anyhow!("User should have connected"))
} }
} }

5
server/src/server/socket_manager.rs

@ -1,10 +1,9 @@
use std::collections::HashMap; use std::collections::HashMap;
use tokio::{ use tokio::{
io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, io::{AsyncWriteExt, BufWriter},
net::{tcp::OwnedWriteHalf, TcpListener}, net::{tcp::OwnedWriteHalf},
sync::RwLock, sync::RwLock,
}; };
use log::info;
use uuid::Uuid; use uuid::Uuid;
use anyhow::Result; use anyhow::Result;
use prost::Message; use prost::Message;

Loading…
Cancel
Save