@@ -7,24 +7,22 @@ use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
77use crate :: net:: internal_packets:: { ClientHandlerMessage , MainThreadMessage , NetworkThreadMessage } ;
88use crate :: server:: player:: player:: ClientId ;
99
10- /// runs the network thread. It is very important that nothing here panics without alerting the main thread.
11- /// if a handle_client panics, it should send a disconnect player to the main thread. (however we dont have anything that could panic there atm)
10+ type ClientMap = HashMap < ClientId , UnboundedSender < ClientHandlerMessage > > ;
11+
1212pub async fn run_network_thread (
1313 mut network_rx : UnboundedReceiver < NetworkThreadMessage > ,
1414 network_tx : UnboundedSender < NetworkThreadMessage > ,
1515 main_tx : UnboundedSender < MainThreadMessage > ,
1616) {
17- let listener = TcpListener :: bind ( "127.0.0.1:4972" ) . await . unwrap_or_else ( |err| {
18- let _ = main_tx. send ( MainThreadMessage :: Abort { reason : format ! ( "TCP failed to bind: {}" , err) } ) ;
19- panic ! ( "{}" , err)
20- } ) ;
17+ let listener = TcpListener :: bind ( "127.0.0.1:4972" ) . await . unwrap ( ) ;
2118 println ! ( "Network thread listening on 127.0.0.1:4972" ) ;
2219
23- let mut clients: HashMap < ClientId , UnboundedSender < ClientHandlerMessage > > = HashMap :: new ( ) ;
20+ let mut clients: ClientMap = HashMap :: new ( ) ;
2421 let mut client_id_counter: ClientId = 1 ;
2522
2623 loop {
2724 tokio:: select! {
25+ // a client failing to connect here is recoverable and doesnt really do anything, so we can just ignore it.
2826 Ok ( ( socket, _) ) = listener. accept( ) => {
2927 let client_id: ClientId = client_id_counter;
3028 client_id_counter += 1 ;
@@ -35,28 +33,39 @@ pub async fn run_network_thread(
3533 tokio:: spawn( handle_client( client_id, socket, client_rx, main_tx. clone( ) , network_tx. clone( ) ) ) ;
3634 }
3735
36+ // this can never be none since this function owns a network_tx.
3837 Some ( msg) = network_rx. recv( ) => {
39- match msg {
38+ // we can just discard main thread -> network thread messages with a disconnected client_id
39+ // as the main thread either already has or will be be informed shortly of this issue
40+ match msg {
4041 NetworkThreadMessage :: SendPackets { client_id, buffer } => {
4142 if let Some ( client_tx) = clients. get( & client_id) {
42- let _ = client_tx. send( ClientHandlerMessage :: Send ( buffer) ) ;
43+ if let Err ( e) = client_tx. send( ClientHandlerMessage :: Send ( buffer) ) {
44+ eprintln!( "Client {} handler dropped its reciever: {}" , client_id, e) ;
45+ disconnect_client( client_id, & main_tx, & mut clients) ;
46+ }
4347 }
4448 }
45-
49+
4650 NetworkThreadMessage :: DisconnectClient { client_id } => {
4751 if let Some ( client_tx) = clients. get( & client_id) {
48- let _ = client_tx. send( ClientHandlerMessage :: CloseHandler ) ;
49- } else {
50- eprintln!( "Attempted to disconnect nonexistent client {}" , client_id) ;
52+ if let Err ( e) = client_tx. send( ClientHandlerMessage :: CloseHandler ) {
53+ eprintln!( "Client {} handler dropped its reciever: {}" , client_id, e) ;
54+ disconnect_client( client_id, & main_tx, & mut clients) ;
55+ }
5156 }
5257 }
53-
58+
5459 NetworkThreadMessage :: ConnectionClosed { client_id } => {
55- let _ = main_tx. send( MainThreadMessage :: ClientDisconnected { client_id } ) ;
56- clients. remove( & client_id) ;
60+ disconnect_client( client_id, & main_tx, & mut clients) ;
5761 }
5862 }
5963 }
6064 }
6165 }
66+ }
67+
68+ fn disconnect_client ( client_id : ClientId , main_tx : & UnboundedSender < MainThreadMessage > , clients : & mut ClientMap ) {
69+ main_tx. send ( MainThreadMessage :: ClientDisconnected { client_id } ) . expect ( "Main thread should never drop its network reciever." ) ;
70+ clients. remove ( & client_id) ;
6271}
0 commit comments