Browse Source

Always disconnect client gracefully on handler error

Errors in the handler do not cause the client session to be removed,
meaning they will not be able to reconnect due to their username already
being in use.

Make sure that clients are disconnected on handler errors.
Frans Bergman 2 years ago
parent
commit
99f0608e08
2 changed files with 33 additions and 32 deletions
  1. 20 32
      src/server/client/client_worker.rs
  2. 13 0
      src/server/client/handler.rs

+ 20 - 32
src/server/client/client_worker.rs

@@ -81,29 +81,33 @@ impl<C: ControlChannel + 'static, A: AudioChannel + 'static> ClientWorker<C, A>
     }
 
     async fn run_handler_loop(
-        handler: Handler<C, A>,
+        mut handler: Handler<C, A>,
         control_channel: Arc<C>,
         event_receiver: Receiver<ServerEvent>,
         channel_receiver: Receiver<A>,
     ) -> JoinHandle<()> {
         tokio::spawn(async move {
-            match Self::handler_loop(handler, control_channel, event_receiver, channel_receiver)
-                .await
+            match Self::handler_loop(
+                &mut handler,
+                control_channel,
+                event_receiver,
+                channel_receiver,
+            )
+            .await
             {
-                Err(HandlerError::IO(_)) => {
-                    todo!()
-                }
-                Err(HandlerError::EventReceiverClosed) => {
-                    error!("Server event receiver have been dropped");
-                }
                 Ok(_) => {}
+                Err(e) => error!("Error in client worker handler: {}", e),
             }
+            match handler.self_disconnected().await {
+                Ok(_) => {}
+                Err(e) => error!("Disconnection failed: {}", e),
+            };
         })
     }
 
     // TODO cleaner solution
     async fn handler_loop(
-        mut handler: Handler<C, A>,
+        handler: &mut Handler<C, A>,
         control_channel: Arc<C>,
         mut event_receiver: Receiver<ServerEvent>,
         mut channel_receiver: Receiver<A>,
@@ -116,16 +120,9 @@ impl<C: ControlChannel + 'static, A: AudioChannel + 'static> ClientWorker<C, A>
         loop {
             tokio::select! {
                 result = &mut msg_recv_fut => {
-                    match result {
-                        Ok(msg) => {
-                            msg_recv_fut.set(control_channel.receive());
-                            handler.handle_message(msg).await?;
-                        }
-                        Err(_) => {
-                            handler.self_disconnected().await?;
-                            break;
-                        }
-                    }
+                    let msg = result?;
+                    msg_recv_fut.set(control_channel.receive());
+                    handler.handle_message(msg).await?;
                 }
                 Some(event) = event_receiver.recv() => {
                     handler.handle_server_event(event).await?;
@@ -137,21 +134,12 @@ impl<C: ControlChannel + 'static, A: AudioChannel + 'static> ClientWorker<C, A>
                     audio_recv_fut.set(Self::recv(audio_channel.clone()));
                 }
                 Some(result) = &mut audio_recv_fut => {
-                    match result {
-                        Ok(packet) => {
-                            audio_recv_fut.set(Self::recv(audio_channel.clone()));
-                            handler.handle_audio_packet(packet).await?;
-                        }
-                        Err(_) => {
-                            handler.self_disconnected().await?;
-                            break;
-                        }
-                    }
+                    let packet = result?;
+                    audio_recv_fut.set(Self::recv(audio_channel.clone()));
+                    handler.handle_audio_packet(packet).await?;
                 }
             };
         }
-
-        Ok(())
     }
 
     async fn recv(

+ 13 - 0
src/server/client/handler.rs

@@ -57,6 +57,19 @@ pub enum HandlerError {
     EventReceiverClosed,
 }
 
+impl fmt::Display for HandlerError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match &self {
+            HandlerError::IO(e) => {
+                write!(f, "{}", e)
+            }
+            HandlerError::EventReceiverClosed => {
+                write!(f, "Server event receiver have been dropped")
+            }
+        }
+    }
+}
+
 pub enum ConnectionSetupError {
     IO(std::io::Error),
     Reject(Reject),