- Use logging facilities instead of plain println!
- Parse malformed messages, parser doesn't get stuck anymore
--- a/gameServer2/Cargo.toml Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/Cargo.toml Sat Jan 14 22:30:09 2017 +0300
@@ -9,3 +9,5 @@
slab = "0.3"
netbuf = "0.3.8"
nom = "2.0"
+env_logger = "0.3.5"
+log = "0.3.6"
--- a/gameServer2/src/main.rs Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/main.rs Sat Jan 14 22:30:09 2017 +0300
@@ -4,6 +4,9 @@
extern crate netbuf;
#[macro_use]
extern crate nom;
+#[macro_use]
+extern crate log;
+extern crate env_logger;
//use std::io::*;
//use rand::Rng;
@@ -16,7 +19,9 @@
mod protocol;
fn main() {
- println!("Hedgewars game server, protocol {}", utils::PROTOCOL_VERSION);
+ env_logger::init().unwrap();
+
+ info!("Hedgewars game server, protocol {}", utils::PROTOCOL_VERSION);
let address = "0.0.0.0:46631".parse().unwrap();
let listener = TcpListener::bind(&address).unwrap();
@@ -43,6 +48,12 @@
tok => server.client_writable(&poll, tok).unwrap(),
}
}
+ if event.kind().is_hup() || event.kind().is_error() {
+ match event.token() {
+ utils::SERVER => unreachable!(),
+ tok => server.client_error(&poll, tok).unwrap(),
+ }
+ }
}
}
}
--- a/gameServer2/src/protocol/messages.rs Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/protocol/messages.rs Sat Jan 14 22:30:09 2017 +0300
@@ -67,6 +67,9 @@
Delete(&'a str),
SaveRoom(&'a str),
LoadRoom(&'a str),
+ Connected(u32),
+ Malformed,
+ Empty,
}
pub fn number<T: From<u8>
@@ -101,6 +104,12 @@
=> "PING\n\n".to_string(),
&HWProtocolMessage::Pong
=> "PONG\n\n".to_string(),
+ &HWProtocolMessage::Connected(protocol_version)
+ => construct_message(&[
+ "CONNECTED",
+ "Hedgewars server http://www.hedgewars.org/",
+ &protocol_version.to_string()
+ ]),
&HWProtocolMessage::Bye(msg)
=> construct_message(&["BYE", msg]),
&HWProtocolMessage::LobbyLeft(msg)
--- a/gameServer2/src/protocol/parser.rs Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/protocol/parser.rs Sat Jan 14 22:30:09 2017 +0300
@@ -99,13 +99,24 @@
(BanNick(n, r, t)))
));
-named!(message<&[u8], HWProtocolMessage>, terminated!(alt!(
- basic_message
- | one_param_message
- | cmd_message
- | complex_message
- ), end_of_message
-));
+named!(malformed_message<&[u8], HWProtocolMessage>,
+ do_parse!(separated_list!(eol, a_line) >> (Malformed)));
+
+named!(empty_message<&[u8], HWProtocolMessage>,
+ do_parse!(alt!(end_of_message | eol) >> (Empty)));
+
+named!(message<&[u8], HWProtocolMessage>, alt!(terminated!(
+ alt!(
+ basic_message
+ | one_param_message
+ | cmd_message
+ | complex_message
+ | malformed_message
+ ), end_of_message
+ )
+ | empty_message
+ )
+);
named!(pub extract_messages<&[u8], Vec<HWProtocolMessage> >, many0!(complete!(message)));
@@ -120,5 +131,8 @@
assert_eq!(message(b"CMD\nwatch\ndemo\n\n"), IResult::Done(&b""[..], Watch("demo")));
assert_eq!(message(b"BAN\nme\nbad\n77\n\n"), IResult::Done(&b""[..], Ban("me", "bad", 77)));
- assert_eq!(extract_messages(b"PING\n\nPING\n\nP"), IResult::Done(&b"P"[..], vec![Ping, Ping]));
+ assert_eq!(extract_messages(b"PING\n\nPING\n\nP"), IResult::Done(&b"P"[..], vec![Ping, Ping]));
+ assert_eq!(extract_messages(b"SING\n\nPING\n\n"), IResult::Done(&b""[..], vec![Malformed, Ping]));
+ assert_eq!(extract_messages(b"\n\n\n\nPING\n\n"), IResult::Done(&b""[..], vec![Empty, Empty, Ping]));
+ assert_eq!(extract_messages(b"\n\n\nPING\n\n"), IResult::Done(&b""[..], vec![Empty, Empty, Ping]));
}
--- a/gameServer2/src/server/client.rs Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/server/client.rs Sat Jan 14 22:30:09 2017 +0300
@@ -9,6 +9,7 @@
use protocol::ProtocolDecoder;
use protocol::messages;
use protocol::messages::HWProtocolMessage::*;
+use log;
pub struct HWClient {
sock: TcpStream,
@@ -26,13 +27,11 @@
}
pub fn register(&mut self, poll: &Poll, token: Token) {
- poll.register(&self.sock, token, Ready::readable(),
+ poll.register(&self.sock, token, Ready::all(),
PollOpt::edge())
.ok().expect("could not register socket with event loop");
- self.send_raw_msg(
- format!("CONNECTED\nHedgewars server http://www.hedgewars.org/\n{}\n\n"
- , utils::PROTOCOL_VERSION).as_bytes());
+ self.send_msg(Connected(utils::PROTOCOL_VERSION));
}
fn send_raw_msg(&mut self, msg: &[u8]) {
@@ -51,14 +50,16 @@
pub fn readable(&mut self, poll: &Poll) -> io::Result<()> {
let v = self.decoder.read_from(&mut self.sock)?;
- println!("Read {} bytes", v);
+ debug!("Read {} bytes", v);
let mut response = Vec::new();
{
let msgs = self.decoder.extract_messages();
for msg in msgs {
match msg {
Ping => response.push(Pong),
- _ => println!("Unknown message")
+ Malformed => warn!("Malformed/unknown message"),
+ Empty => warn!("Empty message"),
+ _ => unimplemented!(),
}
}
}
@@ -73,4 +74,9 @@
self.buf_out.write_to(&mut self.sock)?;
Ok(())
}
+
+ pub fn error(&mut self, poll: &Poll) -> io::Result<()> {
+ debug!("Client error");
+ Ok(())
+ }
}
--- a/gameServer2/src/server/server.rs Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/server/server.rs Sat Jan 14 22:30:09 2017 +0300
@@ -31,7 +31,7 @@
pub fn accept(&mut self, poll: &Poll) -> io::Result<()> {
let (sock, addr) = self.listener.accept()?;
- println!("Connected: {}", addr);
+ info!("Connected: {}", addr);
let client = HWClient::new(sock);
let token = self.clients.insert(client)
@@ -51,6 +51,11 @@
token: Token) -> io::Result<()> {
self.clients[token].writable(poll)
}
+
+ pub fn client_error(&mut self, poll: &Poll,
+ token: Token) -> io::Result<()> {
+ self.clients[token].error(poll)
+ }
}
--- a/gameServer2/src/utils.rs Sat Jan 14 00:46:52 2017 +0300
+++ b/gameServer2/src/utils.rs Sat Jan 14 22:30:09 2017 +0300
@@ -1,4 +1,4 @@
use mio;
-pub const PROTOCOL_VERSION : i32 = 3;
+pub const PROTOCOL_VERSION : u32 = 3;
pub const SERVER: mio::Token = mio::Token(1000000000 + 0);