2019-09-04 09:17:22 -07:00
|
|
|
use std::thread;
|
2019-12-18 19:31:25 -08:00
|
|
|
use log::warn;
|
2019-09-04 09:17:22 -07:00
|
|
|
use mio::{Events, Poll, Token, Ready, PollOpt};
|
|
|
|
use mio_extras::channel::{channel, Sender, Receiver};
|
|
|
|
|
|
|
|
use crate::common::clientpool::{ClientPool, ClientAction, ClientPoolAction};
|
2019-09-15 15:37:35 -07:00
|
|
|
use crate::common::serverstate::{RecvServerPacket, SendServerPacket, ServerState, OnConnect};
|
2019-09-04 09:17:22 -07:00
|
|
|
|
|
|
|
fn recv_from_clientpool<STATE, S, R, E>(state: &mut STATE,
|
|
|
|
pool_recv: &Receiver<ClientPoolAction<R>>,
|
|
|
|
pool_send: &Sender<ClientAction<S>>) where
|
|
|
|
STATE: ServerState<SendPacket=S, RecvPacket=R, PacketError=E>,
|
|
|
|
S: SendServerPacket,
|
|
|
|
R: RecvServerPacket,
|
|
|
|
E: std::fmt::Debug,
|
|
|
|
{
|
|
|
|
loop {
|
|
|
|
match pool_recv.try_recv() {
|
|
|
|
Ok(incoming) => {
|
|
|
|
match incoming {
|
|
|
|
ClientPoolAction::NewClient(client_id) => {
|
2019-09-15 13:15:19 -07:00
|
|
|
for s in state.on_connect(client_id).into_iter() {
|
2019-09-04 09:17:22 -07:00
|
|
|
match s {
|
|
|
|
OnConnect::Cipher((in_cipher, out_cipher)) => {
|
|
|
|
pool_send.send(ClientAction::EncryptionKeys(client_id, in_cipher, out_cipher)).unwrap();
|
|
|
|
}
|
|
|
|
OnConnect::Packet(pkt) => {
|
|
|
|
pool_send.send(ClientAction::Packet(client_id, pkt)).unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
ClientPoolAction::Packet(client_id, pkt) => {
|
|
|
|
let to_send = state.handle(client_id, &pkt);
|
2019-09-15 13:17:49 -07:00
|
|
|
match to_send {
|
|
|
|
Ok(pkts) => {
|
|
|
|
for p in pkts {
|
|
|
|
pool_send.send(ClientAction::Packet(p.0, p.1)).unwrap();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(err) => {
|
|
|
|
// TODO: break?
|
2019-12-18 19:31:25 -08:00
|
|
|
warn!("[handler error]: {:?} {:?}", client_id, err);
|
2019-09-15 13:17:49 -07:00
|
|
|
}
|
2019-09-04 09:17:22 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(_err) => {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn mainloop<STATE, S, R, E>(mut state: STATE, port: u16) where
|
|
|
|
STATE: ServerState<SendPacket=S, RecvPacket=R, PacketError=E> + Send + 'static,
|
|
|
|
S: SendServerPacket + std::fmt::Debug + Send + 'static,
|
|
|
|
R: RecvServerPacket + std::fmt::Debug + Send + 'static,
|
|
|
|
E: std::fmt::Debug,
|
|
|
|
{
|
|
|
|
let (pool_send, pool_recv) = channel();
|
|
|
|
//let (patch_handler_send, patch_handler_recv) = channel::<ClientPoolAction<RecvPatchPacket>>();
|
|
|
|
let (handler_send, handler_recv) = channel();
|
|
|
|
|
|
|
|
//let sender_clone = patch_handler_send.clone();
|
|
|
|
let client_thread = thread::spawn(move || {
|
|
|
|
let clientpool = ClientPool::new(pool_recv, handler_send, port);
|
|
|
|
clientpool.io_loop();
|
|
|
|
});
|
|
|
|
|
2019-09-15 15:37:35 -07:00
|
|
|
//let handler_threadpool = threadpool::ThreadPool::new(4);
|
2019-09-04 09:17:22 -07:00
|
|
|
let handler_thread = thread::spawn(move || {
|
|
|
|
let poll = Poll::new().unwrap();
|
|
|
|
poll.register(&handler_recv, Token(0), Ready::readable(), PollOpt::edge()).unwrap();
|
|
|
|
|
|
|
|
let mut events = Events::with_capacity(1024);
|
|
|
|
|
|
|
|
loop {
|
|
|
|
poll.poll(&mut events, None).unwrap();
|
|
|
|
|
|
|
|
for event in &events {
|
|
|
|
match event.token() {
|
|
|
|
Token(0) => recv_from_clientpool(&mut state, &handler_recv, &pool_send),
|
|
|
|
_ => panic!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
client_thread.join().unwrap();
|
|
|
|
handler_thread.join().unwrap();
|
|
|
|
}
|