Browse Source

Refactor ServerConnection to implement Handler.

wip
Titouan Rigoudy 9 years ago
parent
commit
ff640b69d9
4 changed files with 66 additions and 54 deletions
  1. +3
    -46
      src/main.rs
  2. +17
    -3
      src/proto/packet.rs
  3. +2
    -0
      src/proto/server.rs
  4. +44
    -5
      src/server.rs

+ 3
- 46
src/main.rs View File

@ -16,43 +16,6 @@ use mio::tcp::TcpStream;
use proto::PacketStream;
use server::ServerConnection;
const SERVER_TOKEN: Token = Token(0);
#[derive(Debug)]
struct ConnectionHandler {
server_conn: ServerConnection<TcpStream>,
}
impl ConnectionHandler {
fn new(server_conn: ServerConnection<TcpStream>) -> Self {
ConnectionHandler{
server_conn: server_conn,
}
}
}
impl Handler for ConnectionHandler {
type Timeout = ();
type Message = ();
fn ready(&mut self, event_loop: &mut EventLoop<Self>,
token: Token, event_set: EventSet) {
match token {
SERVER_TOKEN => {
if event_set.is_readable() {
self.server_conn.server_readable();
}
if event_set.is_writable() {
self.server_conn.server_writable();
}
},
_ => unreachable!("Unknown token"),
}
}
}
fn connect(hostname: &str, port: u16) -> io::Result<TcpStream> {
for sock_addr in try!((hostname, port).to_socket_addrs()) {
if let Ok(stream) = TcpStream::connect(&sock_addr) {
@ -71,15 +34,9 @@ fn main() {
let mut event_loop = EventLoop::new().unwrap();
event_loop.register(
&stream,
SERVER_TOKEN,
EventSet::readable() | EventSet::writable(),
PollOpt::level()).unwrap();
let packet_stream = PacketStream::new(stream);
let server_conn = ServerConnection::new(packet_stream);
let mut handler = ConnectionHandler::new(server_conn);
let mut server_conn = ServerConnection::new(packet_stream);
server_conn.register_all(&mut event_loop);
event_loop.run(&mut handler).unwrap();
event_loop.run(&mut server_conn).unwrap();
}

+ 17
- 3
src/proto/packet.rs View File

@ -4,7 +4,9 @@ use std::io::{Cursor, Read, Write};
use std::mem;
use byteorder::{ByteOrder, LittleEndian, ReadBytesExt, WriteBytesExt};
use mio::{TryRead, TryWrite};
use mio::{
Evented, EventLoop, EventSet, Handler, PollOpt, Token, TryRead, TryWrite
};
use mio::tcp::TcpStream;
const MAX_PACKET_SIZE: usize = 1 << 20; // 1 MiB
@ -126,14 +128,14 @@ enum State {
}
#[derive(Debug)]
pub struct PacketStream<T: Read + Write> {
pub struct PacketStream<T: Read + Write + Evented> {
stream: T,
state: State,
num_bytes_left: usize,
buffer: Vec<u8>,
}
impl<T: Read + Write> PacketStream<T> {
impl<T: Read + Write + Evented> PacketStream<T> {
pub fn new(stream: T) -> Self {
PacketStream {
@ -188,4 +190,16 @@ impl<T: Read + Write> PacketStream<T> {
Some(_) => Ok(Some(()))
}
}
pub fn register<U: Handler>(&self, event_loop: &mut EventLoop<U>,
token: Token, event_set: EventSet,
poll_opt: PollOpt) {
event_loop.register(&self.stream, token, event_set, poll_opt);
}
pub fn reregister<U: Handler>(&self, event_loop: &mut EventLoop<U>,
token: Token, event_set: EventSet,
poll_opt: PollOpt) {
event_loop.reregister(&self.stream, token, event_set, poll_opt);
}
}

+ 2
- 0
src/proto/server.rs View File

@ -10,6 +10,7 @@ const VERSION_MAJOR: u32 = 181;
const VERSION_MINOR: u32 = 0;
const CODE_LOGIN: u32 = 1;
const CODE_ROOM_LIST: u32 = 64;
pub enum ServerRequest {
LoginRequest(LoginRequest),
@ -116,3 +117,4 @@ impl LoginResponse {
Ok(resp)
}
}

+ 44
- 5
src/server.rs View File

@ -2,8 +2,10 @@ use std::io;
use std::io::{Read, Write};
use std::net::Ipv4Addr;
use config;
use mio::{EventLoop, EventSet, Handler, PollOpt, Token};
use mio::tcp::TcpStream;
use config;
use proto::{Packet, PacketStream};
use proto::server::{
LoginRequest,
@ -20,16 +22,25 @@ enum State {
}
#[derive(Debug)]
pub struct ServerConnection<T: Read + Write> {
pub struct ServerConnection {
state: State,
server_stream: PacketStream<T>,
token_counter: usize,
server_token: Token,
server_stream: PacketStream<TcpStream>,
server_interest: EventSet,
}
impl<T: Read + Write> ServerConnection<T> {
pub fn new(server_stream: PacketStream<T>) -> Self {
impl ServerConnection {
pub fn new(server_stream: PacketStream<TcpStream>) -> Self {
let token_counter = 0;
ServerConnection {
state: State::NotLoggedIn,
token_counter: token_counter,
server_token: Token(token_counter),
server_stream: server_stream,
server_interest: EventSet::writable() | EventSet::readable(),
}
}
@ -38,6 +49,7 @@ impl<T: Read + Write> ServerConnection<T> {
State::NotLoggedIn => {
println!("Logging in...");
self.state = State::LoggingIn;
self.server_interest = EventSet::readable();
let request = ServerRequest::LoginRequest(LoginRequest::new(
config::USERNAME,
config::PASSWORD,
@ -70,6 +82,11 @@ impl<T: Read + Write> ServerConnection<T> {
}
}
pub fn register_all<T: Handler>(&self, event_loop: &mut EventLoop<T>) {
self.server_stream.register(event_loop, self.server_token,
self.server_interest, PollOpt::edge());
}
fn handle_login(&mut self, login: LoginResponse) -> io::Result<()> {
match self.state {
State::LoggingIn => {
@ -107,3 +124,25 @@ impl<T: Read + Write> ServerConnection<T> {
}
}
}
impl Handler for ServerConnection {
type Timeout = ();
type Message = ();
fn ready(&mut self, event_loop: &mut EventLoop<Self>,
token: Token, event_set: EventSet) {
if token == self.server_token {
if event_set.is_writable() {
self.server_writable();
}
if event_set.is_readable() {
self.server_readable();
}
self.server_stream.reregister(
event_loop, token, self.server_interest,
PollOpt::edge() | PollOpt::oneshot())
} else {
unreachable!("Unknown token!");
}
}
}

Loading…
Cancel
Save