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. 169
      server/src/server.rs
  2. 5
      server/src/server/socket_manager.rs

169
server/src/server.rs

@ -1,19 +1,28 @@
// use tonic::transport::Server;
use anyhow::Result;
use log::info;
use log::warn;
use tokio::{
io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter},
net::{tcp::OwnedWriteHalf, TcpListener},
io::{AsyncReadExt, BufReader},
net::TcpListener,
sync::RwLock,
};
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::{
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};
use crate::{
db,
games::RunningGame,
server::{
connection::{
connect, create_lobby, disconnect, get_public_lobbies, join_lobby_with_code, name,
},
game::{get_card_image, on_click},
lobby::{leave, ready, users, vote},
},
server_properties::ServerProperties,
};
use prost::Message;
@ -23,8 +32,8 @@ mod connection;
mod game;
mod lobby;
mod protos;
mod votes;
mod socket_manager;
mod votes;
// use connection::{ConnectionServer, ConnectionService};
// use game::{GameServer, GameService};
@ -119,19 +128,57 @@ pub async fn serve(
let socket_manager = socket_manager.clone();
tokio::spawn(async move {
loop {
let length = reader
.read_u32_le()
.await
.expect("Unexpected inability to read the length of a packet (U32 LE)");
let length = match reader.read_u32_le().await {
Err(e) => match e.kind() {
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)");
let mut data = vec![0; length as usize];
reader
.read_exact(&mut data)
.await
.expect("Error reading packet");
let packet = protos::protocol::ClientServerPacket::decode(data.as_slice())
.expect("Error decoding the data")
.data
.expect("Unexpected data in packet recieved");
match reader.read_exact(&mut data).await {
Err(e) => match e.kind() {
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");
let packet = match protos::protocol::ClientServerPacket::decode(data.as_slice()) {
Err(e) => {
warn!("Error decoding the packet, skipping ({})", e);
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;
match packet {
@ -139,36 +186,72 @@ pub async fn serve(
Data::QueryName(()) => name(&mut service_data, &socket_manager)
.await
.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)
.await
.expect("Error handling connect"),
Data::Disconnect(()) => disconnect(&mut service_data)
.await
.expect("Error handling disconnect"),
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
.expect("Error handling connect"),
Data::Disconnect(()) => {
break;
}
Data::JoinLobby(code) => join_lobby_with_code(&mut service_data, code)
.await
.expect("Error handling join with code"),
Data::CreateLobby(config) => create_lobby(&mut service_data, &socket_manager, config)
.await
.expect("Error handling create lobby"),
Data::CreateLobby(config) => {
create_lobby(&mut service_data, &socket_manager, config)
.await
.expect("Error handling create lobby")
}
Data::QueryGames(()) => connection::games(&mut service_data, &socket_manager)
.await
.expect("Error handling games query"),
Data::QueryPublicLobbies(()) => get_public_lobbies(&mut service_data, &socket_manager)
.await
.expect("Error handling public lobbies query"),
Data::QueryPublicLobbies(()) => {
get_public_lobbies(&mut service_data, &socket_manager)
.await
.expect("Error handling public lobbies query")
}
// LOBBY
Data::QueryUsers(()) => users(&mut service_data, &socket_manager).await.expect("Error handling users query"),
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"),
Data::QueryUsers(()) => users(&mut service_data, &socket_manager)
.await
.expect("Error handling users query"),
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
Data::QueryCardImage(card_kind) => 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")
Data::QueryCardImage(card_kind) => {
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)
}
pub fn new_filled(uuid: Uuid) -> Self {
Self(Some(uuid))
}
// pub fn new_filled(uuid: Uuid) -> Self {
// Self(Some(uuid))
// }
pub fn set(&mut self, uuid: Uuid) {
self.0 = Some(uuid);
@ -215,6 +298,8 @@ impl UserId {
}
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 tokio::{
io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter},
net::{tcp::OwnedWriteHalf, TcpListener},
io::{AsyncWriteExt, BufWriter},
net::{tcp::OwnedWriteHalf},
sync::RwLock,
};
use log::info;
use uuid::Uuid;
use anyhow::Result;
use prost::Message;

Loading…
Cancel
Save