Skip to content

Instantly share code, notes, and snippets.

@reeFridge
Last active October 2, 2017 07:55
Show Gist options
  • Save reeFridge/57e5f2fd7e5633aff1949ba88f53ad37 to your computer and use it in GitHub Desktop.
Save reeFridge/57e5f2fd7e5633aff1949ba88f53ad37 to your computer and use it in GitHub Desktop.
server-app
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