| @ -0,0 +1,166 @@ | |||||
| use std::collections::VecDeque; | |||||
| use std::io; | |||||
| use std::sync::mpsc::Sender; | |||||
| use mio::{EventLoop, EventSet, Handler, PollOpt, Token}; | |||||
| use mio::tcp::TcpStream; | |||||
| use client::{Request, Response}; | |||||
| use proto::{Packet, PacketStream}; | |||||
| use proto::server::*; | |||||
| struct TokenCounter { | |||||
| counter: usize, | |||||
| } | |||||
| impl TokenCounter { | |||||
| fn new() -> Self { | |||||
| TokenCounter { | |||||
| counter: 0, | |||||
| } | |||||
| } | |||||
| fn next(&mut self) -> Token { | |||||
| self.counter += 1; | |||||
| Token(self.counter - 1) | |||||
| } | |||||
| } | |||||
| pub struct ConnectionHandler { | |||||
| token_counter: TokenCounter, | |||||
| server_token: Token, | |||||
| server_stream: PacketStream<TcpStream>, | |||||
| server_queue: VecDeque<Packet>, | |||||
| client_tx: Sender<Response>, | |||||
| } | |||||
| impl ConnectionHandler { | |||||
| pub fn new( | |||||
| server_tcp_stream: TcpStream, client_tx: Sender<Response>, | |||||
| event_loop: &mut EventLoop<Self>) -> Self | |||||
| { | |||||
| let mut token_counter = TokenCounter::new(); | |||||
| let server_token = token_counter.next(); | |||||
| let event_set = EventSet::readable(); | |||||
| let poll_opt = PollOpt::edge() | PollOpt::oneshot(); | |||||
| let server_stream = PacketStream::new(server_tcp_stream); | |||||
| server_stream.register(event_loop, server_token, event_set, poll_opt) | |||||
| .unwrap(); | |||||
| ConnectionHandler { | |||||
| token_counter: token_counter, | |||||
| server_token: server_token, | |||||
| server_stream: server_stream, | |||||
| server_queue: VecDeque::new(), | |||||
| client_tx: client_tx, | |||||
| } | |||||
| } | |||||
| fn read_server_once(&mut self) -> io::Result<bool> { | |||||
| let packet = match try!(self.server_stream.try_read()) { | |||||
| Some(packet) => packet, | |||||
| None => return Ok(false), | |||||
| }; | |||||
| let server_response = try!(ServerResponse::from_packet(packet)); | |||||
| match self.client_tx.send(Response::ServerResponse(server_response)) { | |||||
| Ok(()) => Ok(true), | |||||
| Err(e) => Err(io::Error::new( | |||||
| io::ErrorKind::Other, | |||||
| format!("Send failed on client_tx channel: {}", e))), | |||||
| } | |||||
| } | |||||
| fn write_server_once(&mut self) -> io::Result<bool> { | |||||
| let mut packet = match self.server_queue.pop_front() { | |||||
| Some(packet) => packet, | |||||
| None => return Ok(false), | |||||
| }; | |||||
| match try!(self.server_stream.try_write(&mut packet)) { | |||||
| Some(()) => Ok(true), | |||||
| None => { | |||||
| self.server_queue.push_front(packet); | |||||
| Ok(false) | |||||
| } | |||||
| } | |||||
| } | |||||
| fn notify_server( | |||||
| &mut self, event_loop: &mut EventLoop<Self>, request: ServerRequest) | |||||
| -> io::Result<()> | |||||
| { | |||||
| let packet = try!(request.to_packet()); | |||||
| self.server_queue.push_back(packet); | |||||
| Ok(()) | |||||
| } | |||||
| fn reregister_server(&mut self, event_loop: &mut EventLoop<Self>) { | |||||
| let event_set = if self.server_queue.len() > 0 { | |||||
| EventSet::readable() | EventSet::writable() | |||||
| } else { | |||||
| EventSet::readable() | |||||
| }; | |||||
| let poll_opt = PollOpt::edge() | PollOpt::oneshot(); | |||||
| self.server_stream.reregister( | |||||
| event_loop, self.server_token, event_set, poll_opt).unwrap(); | |||||
| } | |||||
| } | |||||
| impl Handler for ConnectionHandler { | |||||
| type Timeout = (); | |||||
| type Message = Request; | |||||
| fn ready(&mut self, event_loop: &mut EventLoop<Self>, | |||||
| token: Token, event_set: EventSet) | |||||
| { | |||||
| if token == self.server_token { | |||||
| if event_set.is_writable() { | |||||
| loop { | |||||
| match self.write_server_once() { | |||||
| Ok(true) => (), | |||||
| Ok(false) => break, | |||||
| Err(e) => { | |||||
| error!("Error writing server: {}", e); | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| if event_set.is_readable() { | |||||
| loop { | |||||
| match self.read_server_once() { | |||||
| Ok(true) => (), | |||||
| Ok(false) => break, | |||||
| Err(e) => { | |||||
| error!("Error reading server: {}", e); | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| self.reregister_server(event_loop); | |||||
| } else { | |||||
| unreachable!("Unknown token!"); | |||||
| } | |||||
| } | |||||
| fn notify(&mut self, event_loop: &mut EventLoop<Self>, request: Request) { | |||||
| match request { | |||||
| Request::ServerRequest(server_request) => { | |||||
| match self.notify_server(event_loop, server_request) { | |||||
| Ok(()) => (), | |||||
| Err(e) => error!("Error processing server request: {}", e), | |||||
| } | |||||
| self.reregister_server(event_loop); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||