Selaa lähdekoodia

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 vuotta sitten
vanhempi
commit
99f0608e08
2 muutettua tiedostoa jossa 33 lisäystä ja 32 poistoa
  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),