소스 검색

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 년 전
부모
커밋
99f0608e08
2개의 변경된 파일33개의 추가작업 그리고 32개의 파일을 삭제
  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),