Last active
October 2, 2017 07:55
-
-
Save reeFridge/57e5f2fd7e5633aff1949ba88f53ad37 to your computer and use it in GitHub Desktop.
server-app
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate mio; | |
use mio::*; | |
use std::io::{self, Read, Write}; | |
use mio::net::{TcpListener, TcpStream}; | |
use std::collections::HashMap; | |
// Setup some tokens to allow us to identify which event is | |
// for which socket. | |
const SERVER: Token = Token(0); | |
struct Client { | |
socket: TcpStream, | |
obj_id: Option<usize> | |
} | |
impl Client { | |
fn new(socket: TcpStream) -> Client { | |
Client { socket: socket, obj_id: None } | |
} | |
} | |
struct Server { | |
clients: HashMap<Token, Client> | |
} | |
impl Server { | |
fn new() -> Server { | |
Server { clients: HashMap::new() } | |
} | |
} | |
fn main() { | |
let addr = "127.0.0.1:7001".parse().unwrap(); | |
// Setup the server socket | |
let listener = TcpListener::bind(&addr).unwrap(); | |
// Create a poll instance | |
let poll = Poll::new().unwrap(); | |
// Start listening for incoming connections | |
poll.register(&listener, SERVER, Ready::readable(), | |
PollOpt::edge()).unwrap(); | |
// Create storage for events | |
let mut events = Events::with_capacity(1024); | |
let mut server = Server::new(); | |
loop { | |
poll.poll(&mut events, None).unwrap(); | |
for event in events.iter() { | |
match event.token() { | |
SERVER => { | |
println!("event: {:?}", event.readiness()); | |
println!("Server token"); | |
println!("new client connected"); | |
let next_index = server.clients.len() + 1; | |
let new_token = Token(next_index); | |
server.clients.insert(new_token, match listener.accept() { | |
Ok((stream, _)) => { | |
poll.register( | |
&stream, | |
new_token, | |
Ready::writable() | Ready::readable(), | |
PollOpt::edge() | |
).unwrap(); | |
Client::new(stream) | |
}, | |
Err(e) => panic!("failed on accept connection: {}", e) | |
}); | |
}, | |
token => { | |
println!("client token: {:?}", token); | |
println!("event: {:?}", event.readiness()); | |
if event.readiness().is_readable() { | |
print!("read from [{:?}]: ", &token); | |
let mut message = String::new(); | |
let mut buf = [0u8, 64]; | |
loop { | |
match server.clients.get_mut(&token).unwrap().socket.read(&mut buf) { | |
Ok(0) => { | |
println!("client with token {:?} disconnected", &token); | |
server.clients.remove(&token); | |
break; | |
}, | |
Ok(_) => { | |
message.push_str(String::from_utf8_lossy(&mut buf).into_owned().as_str()); | |
}, | |
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => { | |
//println!("[end of stream]"); | |
break; | |
}, | |
Err(_) => panic!("Error on read") | |
} | |
} | |
print!("{}", message); | |
if event.readiness().is_writable() { | |
for (t, &mut Client { socket: ref mut client_sock, .. }) in server.clients.iter_mut() { | |
if !t.eq(&token) { | |
client_sock.write_all(message.as_bytes()).unwrap(); | |
} | |
} | |
} | |
} | |
} | |
_ => unreachable!(), | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment