Implement IO listener · feather-rs/feather@2937a03 · GitHub
Skip to content

Commit 2937a03

Browse files
committed
Implement IO listener
1 parent 7bdd3e1 commit 2937a03

6 files changed

Lines changed: 120 additions & 10 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/Cargo.toml

Lines changed: 2 additions & 1 deletion

server/config/feather.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ max-players = 16
1919
default-gamemode = "survival"
2020
difficulty = "normal"
2121
view-distance = 6
22+
address = "127.0.0.1"
23+
port = 25565
2224

2325
[gameplay]
2426
monster-spawning = true

server/src/io/listener.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
use super::*;
2+
use mio::{
3+
net::{TcpListener, TcpStream},
4+
Events, Poll, PollOpt, Ready, Token,
5+
};
6+
7+
const SERVER: Token = Token(0);
8+
const MESSAGE_RECEIVER: Token = Token(1);
9+
10+
pub struct Listener {
11+
address: String,
12+
listener: TcpListener,
13+
poll: Poll,
14+
15+
sender: Sender<ServerToListenerMessage>,
16+
receiver: Receiver<ServerToListenerMessage>,
17+
18+
workers: Vec<Worker>,
19+
}
20+
21+
/// Starts a listener in the current thread,
22+
/// blocking indefinitely until a`ShutDown` message
23+
/// is received.
24+
pub fn start(
25+
address: String,
26+
sender: Sender<ServerToListenerMessage>,
27+
receiver: Receiver<ServerToListenerMessage>,
28+
worker_senders: Vec<Sender<ListenerToWorkerMessage>>,
29+
) {
30+
let poll = Poll::new().unwrap();
31+
32+
let server = TcpListener::bind(&address.parse().unwrap()).unwrap();
33+
34+
poll.register(&server, SERVER, Ready::readable(), PollOpt::edge())
35+
.unwrap();
36+
37+
let mut workers = vec![];
38+
39+
for (i, sender) in worker_senders.into_iter().enumerate() {
40+
let worker = Worker {
41+
sender,
42+
};
43+
workers.push(worker);
44+
}
45+
46+
let mut events = Events::with_capacity(1024);
47+
let mut next_worker_index = 0;
48+
49+
loop {
50+
poll.poll(&mut events, None).unwrap();
51+
52+
for event in &events {
53+
if event.token() == SERVER {
54+
// New connection
55+
if let Ok((stream, addr)) = server.accept() {
56+
info!("Accepting connection from {}", addr);
57+
debug!(
58+
"Connection will be handled by worker #{}",
59+
next_worker_index
60+
);
61+
62+
let message = ListenerToWorkerMessage::NewConnection(stream, addr);
63+
64+
workers[next_worker_index].sender.send(message).unwrap();
65+
66+
if next_worker_index == workers.len() - 1 {
67+
next_worker_index = 0;
68+
} else {
69+
next_worker_index += 1;
70+
}
71+
}
72+
} else if event.token() == MESSAGE_RECEIVER {
73+
// Message from server
74+
if let Ok(message) = receiver.try_recv() {
75+
match message {
76+
ServerToListenerMessage::ShutDown => {
77+
for worker in workers.iter() {
78+
worker.sender.send(ListenerToWorkerMessage::ShutDown).unwrap();
79+
}
80+
return;
81+
}
82+
_ => panic!("IO listener received invalid message from server"),
83+
}
84+
}
85+
}
86+
}
87+
}
88+
}
89+
90+
struct Worker {
91+
sender: Sender<ListenerToWorkerMessage>,
92+
}

server/src/io/mod.rs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,37 @@
11
use feather_core::network::packet::{self, Packet};
2+
use mio_extras::channel::{channel, Receiver, Sender};
3+
use std::net::SocketAddr;
24
use uuid::Uuid;
3-
use mio_extras::channel::{channel, Sender, Receiver};
5+
6+
mod listener;
47

58
pub struct Client(usize);
69

7-
pub enum ServerIoThreadMessage {
8-
SendPacket(Client, Box<Packet>),
9-
NotifyPacketReceived(Client, Box<Packet>),
10+
pub enum ServerToWorkerMessage {
11+
SendPacket(Box<Packet>),
12+
NotifyPacketReceived(Box<Packet>),
13+
NotifyDisconnect,
14+
Disconnect,
15+
}
16+
17+
pub enum ServerToListenerMessage {
18+
ShutDown,
1019
NewClient(NewClientInfo),
11-
NotifyDisconnect(Client),
12-
Disconnect(Client),
20+
}
21+
22+
pub enum ListenerToWorkerMessage {
23+
ShutDown,
24+
NewConnection(mio::net::TcpStream, SocketAddr),
1325
}
1426

1527
pub struct NewClientInfo {
1628
uuid: Uuid,
1729
name: String,
1830
networked_client_id: Client,
19-
sender: Sender<ServerIoThreadMessage>,
20-
receiver: Receiver<ServerIoThreadMessage>,
31+
ip: SocketAddr,
32+
33+
sender: Sender<ServerToWorkerMessage>,
34+
receiver: Receiver<ServerToWorkerMessage>,
2135
}
2236

2337
pub struct NetworkIoManager {}

server/src/main.rs

Lines changed: 1 addition & 1 deletion

0 commit comments

Comments
 (0)