rust/hedgewars-server/src/server/network.rs
changeset 14812 b2beb784e4b5
parent 14808 92225a708bda
child 14835 8ddb5842fe0b
equal deleted inserted replaced
14811:86dc602ed920 14812:b2beb784e4b5
    37 };
    37 };
    38 use std::time::Duration;
    38 use std::time::Duration;
    39 
    39 
    40 const MAX_BYTES_PER_READ: usize = 2048;
    40 const MAX_BYTES_PER_READ: usize = 2048;
    41 const SEND_PING_TIMEOUT: Duration = Duration::from_secs(30);
    41 const SEND_PING_TIMEOUT: Duration = Duration::from_secs(30);
    42 const DROP_CLIENT_TIMEOUT: Duration = Duration::from_secs(10);
    42 const DROP_CLIENT_TIMEOUT: Duration = Duration::from_secs(30);
       
    43 const PING_PROBES_COUNT: u8 = 2;
    43 
    44 
    44 #[derive(Hash, Eq, PartialEq, Copy, Clone)]
    45 #[derive(Hash, Eq, PartialEq, Copy, Clone)]
    45 pub enum NetworkClientState {
    46 pub enum NetworkClientState {
    46     Idle,
    47     Idle,
    47     NeedsWrite,
    48     NeedsWrite,
   302         }
   303         }
   303     }
   304     }
   304 }
   305 }
   305 
   306 
   306 enum TimeoutEvent {
   307 enum TimeoutEvent {
   307     SendPing,
   308     SendPing { probes_count: u8 },
   308     DropClient,
   309     DropClient,
   309 }
   310 }
   310 
   311 
   311 struct TimerData(TimeoutEvent, ClientId);
   312 struct TimerData(TimeoutEvent, ClientId);
   312 
   313 
   321     #[cfg(feature = "official-server")]
   322     #[cfg(feature = "official-server")]
   322     io: IoLayer,
   323     io: IoLayer,
   323     timer: timer::Timer<TimerData>,
   324     timer: timer::Timer<TimerData>,
   324 }
   325 }
   325 
   326 
   326 fn create_ping_timeout(timer: &mut timer::Timer<TimerData>, client_id: ClientId) -> timer::Timeout {
   327 fn create_ping_timeout(
       
   328     timer: &mut timer::Timer<TimerData>,
       
   329     probes_count: u8,
       
   330     client_id: ClientId,
       
   331 ) -> timer::Timeout {
   327     timer.set_timeout(
   332     timer.set_timeout(
   328         SEND_PING_TIMEOUT,
   333         SEND_PING_TIMEOUT,
   329         TimerData(TimeoutEvent::SendPing, client_id),
   334         TimerData(TimeoutEvent::SendPing { probes_count }, client_id),
   330     )
   335     )
   331 }
   336 }
   332 
   337 
   333 fn create_drop_timeout(timer: &mut timer::Timer<TimerData>, client_id: ClientId) -> timer::Timeout {
   338 fn create_drop_timeout(timer: &mut timer::Timer<TimerData>, client_id: ClientId) -> timer::Timeout {
   334     timer.set_timeout(
   339     timer.set_timeout(
   432 
   437 
   433         let client = NetworkClient::new(
   438         let client = NetworkClient::new(
   434             client_id,
   439             client_id,
   435             client_socket,
   440             client_socket,
   436             addr,
   441             addr,
   437             create_ping_timeout(&mut self.timer, client_id),
   442             create_ping_timeout(&mut self.timer, PING_PROBES_COUNT - 1, client_id),
   438         );
   443         );
   439         info!("client {} ({}) added", client.id, client.peer_addr);
   444         info!("client {} ({}) added", client.id, client.peer_addr);
   440         entry.insert(client);
   445         entry.insert(client);
   441 
   446 
   442         client_id
   447         client_id
   471     }
   476     }
   472 
   477 
   473     pub fn handle_timeout(&mut self, poll: &Poll) -> io::Result<()> {
   478     pub fn handle_timeout(&mut self, poll: &Poll) -> io::Result<()> {
   474         while let Some(TimerData(event, client_id)) = self.timer.poll() {
   479         while let Some(TimerData(event, client_id)) = self.timer.poll() {
   475             match event {
   480             match event {
   476                 TimeoutEvent::SendPing => {
   481                 TimeoutEvent::SendPing { probes_count } => {
   477                     if let Some(ref mut client) = self.clients.get_mut(client_id) {
   482                     if let Some(ref mut client) = self.clients.get_mut(client_id) {
   478                         client.send_string(&HWServerMessage::Ping.to_raw_protocol());
   483                         client.send_string(&HWServerMessage::Ping.to_raw_protocol());
   479                         client.write()?;
   484                         client.write()?;
   480                         client.replace_timeout(create_drop_timeout(&mut self.timer, client_id));
   485                         let timeout = if probes_count != 0 {
       
   486                             create_ping_timeout(&mut self.timer, probes_count - 1, client_id)
       
   487                         } else {
       
   488                             create_drop_timeout(&mut self.timer, client_id)
       
   489                         };
       
   490                         client.replace_timeout(timeout);
   481                     }
   491                     }
   482                 }
   492                 }
   483                 TimeoutEvent::DropClient => {
   493                 TimeoutEvent::DropClient => {
   484                     self.operation_failed(
   494                     self.operation_failed(
   485                         poll,
   495                         poll,
   558         self.client_error(poll, client_id)
   568         self.client_error(poll, client_id)
   559     }
   569     }
   560 
   570 
   561     pub fn client_readable(&mut self, poll: &Poll, client_id: ClientId) -> io::Result<()> {
   571     pub fn client_readable(&mut self, poll: &Poll, client_id: ClientId) -> io::Result<()> {
   562         let messages = if let Some(ref mut client) = self.clients.get_mut(client_id) {
   572         let messages = if let Some(ref mut client) = self.clients.get_mut(client_id) {
   563             let timeout = client.replace_timeout(create_ping_timeout(&mut self.timer, client_id));
   573             let timeout = client.replace_timeout(create_ping_timeout(
       
   574                 &mut self.timer,
       
   575                 PING_PROBES_COUNT - 1,
       
   576                 client_id,
       
   577             ));
   564             self.timer.cancel_timeout(&timeout);
   578             self.timer.cancel_timeout(&timeout);
   565             client.read()
   579             client.read()
   566         } else {
   580         } else {
   567             warn!("invalid readable client: {}", client_id);
   581             warn!("invalid readable client: {}", client_id);
   568             Ok((Vec::new(), NetworkClientState::Idle))
   582             Ok((Vec::new(), NetworkClientState::Idle))