equal
deleted
inserted
replaced
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)) |