Struct Server

Source
pub struct Server { /* private fields */ }

Implementations§

Source§

impl Server

Source

pub fn host(ip: &str, port: u16, connection_limit: usize) -> Result<Server>

Begin hosting a TCP server.

Examples found in repository?
examples/simple_server.rs (line 62)
60fn main() -> Result<()> {
61    // Begin hosting a TCP server
62    let mut server = Server::host("127.0.0.1", 7667, 32)?;
63    println!("Hosting on 127.0.0.1:7667...");
64
65    // We are going to keep track of the # of pings we receive from each client, and kick them
66    // after they have sent a certain amount.
67    let mut ping_counters: HashMap<Token, u32> = HashMap::new();
68
69    loop {
70        // Sleep for a lil bit so we don't hog the CPU
71        std::thread::sleep(std::time::Duration::from_millis(100));
72
73        // Run the network tick and process any events it generates
74        for event in server.tick().iter() {
75            match event {
76                ServerEvent::ClientConnected(token, addr) => {
77                    println!(
78                        "Client {} connected from {} ({}/{})",
79                        token.0,
80                        addr.ip(),
81                        server.num_connections(),
82                        server.connection_limit(),
83                    );
84                }
85                ServerEvent::ClientDisconnected(token) => {
86                    println!("Client {} disconnected.", token.0);
87                }
88                ServerEvent::ConnectionRejected(addr) => {
89                    println!(
90                        "Rejected connection from {} (Connection limit reached)",
91                        addr.ip(),
92                    );
93                }
94                ServerEvent::ReceivedPacket(token, byte_count) => {
95                    println!(
96                        "Received packet from client {} ({} bytes)",
97                        token.0, byte_count
98                    );
99                }
100                ServerEvent::SentPacket(token, byte_count) => {
101                    println!("Sent packet to client {} ({} bytes)", token.0, byte_count);
102                }
103                _ => eprintln!("Unhandled ServerEvent!"),
104            }
105        }
106
107        // Process incoming packets
108        for (token, packet) in server.drain_incoming_packets().iter() {
109            match packet.header.id {
110                0x00 => {
111                    let packet = PingPacket::deserialize(&packet.body);
112                    println!("Got ping from client {}: {}", token.0, packet.unwrap().msg);
113
114                    // Increment the ping counter for this client
115                    let counter = ping_counters.entry(*token).or_insert(0);
116                    *counter += 1;
117
118                    if *counter >= 5 {
119                        // Kick the client when they reach 5 pings.
120                        println!("Client {} sent 5 pings. Kicking them.", token.0);
121                        server.kick(*token)?;
122
123                        ping_counters.remove_entry(token);
124                    } else {
125                        // Otherwise just send a ping response (pong).
126                        let pong = PongPacket {
127                            msg: "Pong!".to_owned(),
128                        };
129                        server.send(PacketRecipient::Single(*token), pong);
130                    }
131                }
132                _ => eprintln!("Unhandled packet! id: {}", packet.header.id),
133            }
134        }
135    }
136
137    Ok(())
138}
Source

pub fn num_connections(&self) -> usize

Get the current number of connections.

Examples found in repository?
examples/simple_server.rs (line 81)
60fn main() -> Result<()> {
61    // Begin hosting a TCP server
62    let mut server = Server::host("127.0.0.1", 7667, 32)?;
63    println!("Hosting on 127.0.0.1:7667...");
64
65    // We are going to keep track of the # of pings we receive from each client, and kick them
66    // after they have sent a certain amount.
67    let mut ping_counters: HashMap<Token, u32> = HashMap::new();
68
69    loop {
70        // Sleep for a lil bit so we don't hog the CPU
71        std::thread::sleep(std::time::Duration::from_millis(100));
72
73        // Run the network tick and process any events it generates
74        for event in server.tick().iter() {
75            match event {
76                ServerEvent::ClientConnected(token, addr) => {
77                    println!(
78                        "Client {} connected from {} ({}/{})",
79                        token.0,
80                        addr.ip(),
81                        server.num_connections(),
82                        server.connection_limit(),
83                    );
84                }
85                ServerEvent::ClientDisconnected(token) => {
86                    println!("Client {} disconnected.", token.0);
87                }
88                ServerEvent::ConnectionRejected(addr) => {
89                    println!(
90                        "Rejected connection from {} (Connection limit reached)",
91                        addr.ip(),
92                    );
93                }
94                ServerEvent::ReceivedPacket(token, byte_count) => {
95                    println!(
96                        "Received packet from client {} ({} bytes)",
97                        token.0, byte_count
98                    );
99                }
100                ServerEvent::SentPacket(token, byte_count) => {
101                    println!("Sent packet to client {} ({} bytes)", token.0, byte_count);
102                }
103                _ => eprintln!("Unhandled ServerEvent!"),
104            }
105        }
106
107        // Process incoming packets
108        for (token, packet) in server.drain_incoming_packets().iter() {
109            match packet.header.id {
110                0x00 => {
111                    let packet = PingPacket::deserialize(&packet.body);
112                    println!("Got ping from client {}: {}", token.0, packet.unwrap().msg);
113
114                    // Increment the ping counter for this client
115                    let counter = ping_counters.entry(*token).or_insert(0);
116                    *counter += 1;
117
118                    if *counter >= 5 {
119                        // Kick the client when they reach 5 pings.
120                        println!("Client {} sent 5 pings. Kicking them.", token.0);
121                        server.kick(*token)?;
122
123                        ping_counters.remove_entry(token);
124                    } else {
125                        // Otherwise just send a ping response (pong).
126                        let pong = PongPacket {
127                            msg: "Pong!".to_owned(),
128                        };
129                        server.send(PacketRecipient::Single(*token), pong);
130                    }
131                }
132                _ => eprintln!("Unhandled packet! id: {}", packet.header.id),
133            }
134        }
135    }
136
137    Ok(())
138}
Source

pub fn connection_limit(&self) -> usize

Get the maximum number of connections allowed.

Examples found in repository?
examples/simple_server.rs (line 82)
60fn main() -> Result<()> {
61    // Begin hosting a TCP server
62    let mut server = Server::host("127.0.0.1", 7667, 32)?;
63    println!("Hosting on 127.0.0.1:7667...");
64
65    // We are going to keep track of the # of pings we receive from each client, and kick them
66    // after they have sent a certain amount.
67    let mut ping_counters: HashMap<Token, u32> = HashMap::new();
68
69    loop {
70        // Sleep for a lil bit so we don't hog the CPU
71        std::thread::sleep(std::time::Duration::from_millis(100));
72
73        // Run the network tick and process any events it generates
74        for event in server.tick().iter() {
75            match event {
76                ServerEvent::ClientConnected(token, addr) => {
77                    println!(
78                        "Client {} connected from {} ({}/{})",
79                        token.0,
80                        addr.ip(),
81                        server.num_connections(),
82                        server.connection_limit(),
83                    );
84                }
85                ServerEvent::ClientDisconnected(token) => {
86                    println!("Client {} disconnected.", token.0);
87                }
88                ServerEvent::ConnectionRejected(addr) => {
89                    println!(
90                        "Rejected connection from {} (Connection limit reached)",
91                        addr.ip(),
92                    );
93                }
94                ServerEvent::ReceivedPacket(token, byte_count) => {
95                    println!(
96                        "Received packet from client {} ({} bytes)",
97                        token.0, byte_count
98                    );
99                }
100                ServerEvent::SentPacket(token, byte_count) => {
101                    println!("Sent packet to client {} ({} bytes)", token.0, byte_count);
102                }
103                _ => eprintln!("Unhandled ServerEvent!"),
104            }
105        }
106
107        // Process incoming packets
108        for (token, packet) in server.drain_incoming_packets().iter() {
109            match packet.header.id {
110                0x00 => {
111                    let packet = PingPacket::deserialize(&packet.body);
112                    println!("Got ping from client {}: {}", token.0, packet.unwrap().msg);
113
114                    // Increment the ping counter for this client
115                    let counter = ping_counters.entry(*token).or_insert(0);
116                    *counter += 1;
117
118                    if *counter >= 5 {
119                        // Kick the client when they reach 5 pings.
120                        println!("Client {} sent 5 pings. Kicking them.", token.0);
121                        server.kick(*token)?;
122
123                        ping_counters.remove_entry(token);
124                    } else {
125                        // Otherwise just send a ping response (pong).
126                        let pong = PongPacket {
127                            msg: "Pong!".to_owned(),
128                        };
129                        server.send(PacketRecipient::Single(*token), pong);
130                    }
131                }
132                _ => eprintln!("Unhandled packet! id: {}", packet.header.id),
133            }
134        }
135    }
136
137    Ok(())
138}
Source

pub fn drain_incoming_packets(&mut self) -> Vec<(Token, Packet)>

Drain any incoming packets and return them.

Examples found in repository?
examples/simple_server.rs (line 108)
60fn main() -> Result<()> {
61    // Begin hosting a TCP server
62    let mut server = Server::host("127.0.0.1", 7667, 32)?;
63    println!("Hosting on 127.0.0.1:7667...");
64
65    // We are going to keep track of the # of pings we receive from each client, and kick them
66    // after they have sent a certain amount.
67    let mut ping_counters: HashMap<Token, u32> = HashMap::new();
68
69    loop {
70        // Sleep for a lil bit so we don't hog the CPU
71        std::thread::sleep(std::time::Duration::from_millis(100));
72
73        // Run the network tick and process any events it generates
74        for event in server.tick().iter() {
75            match event {
76                ServerEvent::ClientConnected(token, addr) => {
77                    println!(
78                        "Client {} connected from {} ({}/{})",
79                        token.0,
80                        addr.ip(),
81                        server.num_connections(),
82                        server.connection_limit(),
83                    );
84                }
85                ServerEvent::ClientDisconnected(token) => {
86                    println!("Client {} disconnected.", token.0);
87                }
88                ServerEvent::ConnectionRejected(addr) => {
89                    println!(
90                        "Rejected connection from {} (Connection limit reached)",
91                        addr.ip(),
92                    );
93                }
94                ServerEvent::ReceivedPacket(token, byte_count) => {
95                    println!(
96                        "Received packet from client {} ({} bytes)",
97                        token.0, byte_count
98                    );
99                }
100                ServerEvent::SentPacket(token, byte_count) => {
101                    println!("Sent packet to client {} ({} bytes)", token.0, byte_count);
102                }
103                _ => eprintln!("Unhandled ServerEvent!"),
104            }
105        }
106
107        // Process incoming packets
108        for (token, packet) in server.drain_incoming_packets().iter() {
109            match packet.header.id {
110                0x00 => {
111                    let packet = PingPacket::deserialize(&packet.body);
112                    println!("Got ping from client {}: {}", token.0, packet.unwrap().msg);
113
114                    // Increment the ping counter for this client
115                    let counter = ping_counters.entry(*token).or_insert(0);
116                    *counter += 1;
117
118                    if *counter >= 5 {
119                        // Kick the client when they reach 5 pings.
120                        println!("Client {} sent 5 pings. Kicking them.", token.0);
121                        server.kick(*token)?;
122
123                        ping_counters.remove_entry(token);
124                    } else {
125                        // Otherwise just send a ping response (pong).
126                        let pong = PongPacket {
127                            msg: "Pong!".to_owned(),
128                        };
129                        server.send(PacketRecipient::Single(*token), pong);
130                    }
131                }
132                _ => eprintln!("Unhandled packet! id: {}", packet.header.id),
133            }
134        }
135    }
136
137    Ok(())
138}
Source

pub fn kick(&mut self, connection_token: Token) -> Result<()>

Kick a connection from the server.

Examples found in repository?
examples/simple_server.rs (line 121)
60fn main() -> Result<()> {
61    // Begin hosting a TCP server
62    let mut server = Server::host("127.0.0.1", 7667, 32)?;
63    println!("Hosting on 127.0.0.1:7667...");
64
65    // We are going to keep track of the # of pings we receive from each client, and kick them
66    // after they have sent a certain amount.
67    let mut ping_counters: HashMap<Token, u32> = HashMap::new();
68
69    loop {
70        // Sleep for a lil bit so we don't hog the CPU
71        std::thread::sleep(std::time::Duration::from_millis(100));
72
73        // Run the network tick and process any events it generates
74        for event in server.tick().iter() {
75            match event {
76                ServerEvent::ClientConnected(token, addr) => {
77                    println!(
78                        "Client {} connected from {} ({}/{})",
79                        token.0,
80                        addr.ip(),
81                        server.num_connections(),
82                        server.connection_limit(),
83                    );
84                }
85                ServerEvent::ClientDisconnected(token) => {
86                    println!("Client {} disconnected.", token.0);
87                }
88                ServerEvent::ConnectionRejected(addr) => {
89                    println!(
90                        "Rejected connection from {} (Connection limit reached)",
91                        addr.ip(),
92                    );
93                }
94                ServerEvent::ReceivedPacket(token, byte_count) => {
95                    println!(
96                        "Received packet from client {} ({} bytes)",
97                        token.0, byte_count
98                    );
99                }
100                ServerEvent::SentPacket(token, byte_count) => {
101                    println!("Sent packet to client {} ({} bytes)", token.0, byte_count);
102                }
103                _ => eprintln!("Unhandled ServerEvent!"),
104            }
105        }
106
107        // Process incoming packets
108        for (token, packet) in server.drain_incoming_packets().iter() {
109            match packet.header.id {
110                0x00 => {
111                    let packet = PingPacket::deserialize(&packet.body);
112                    println!("Got ping from client {}: {}", token.0, packet.unwrap().msg);
113
114                    // Increment the ping counter for this client
115                    let counter = ping_counters.entry(*token).or_insert(0);
116                    *counter += 1;
117
118                    if *counter >= 5 {
119                        // Kick the client when they reach 5 pings.
120                        println!("Client {} sent 5 pings. Kicking them.", token.0);
121                        server.kick(*token)?;
122
123                        ping_counters.remove_entry(token);
124                    } else {
125                        // Otherwise just send a ping response (pong).
126                        let pong = PongPacket {
127                            msg: "Pong!".to_owned(),
128                        };
129                        server.send(PacketRecipient::Single(*token), pong);
130                    }
131                }
132                _ => eprintln!("Unhandled packet! id: {}", packet.header.id),
133            }
134        }
135    }
136
137    Ok(())
138}
Source

pub fn send(&mut self, recipient: PacketRecipient, packet: impl PacketBody)

Send a packet. This function will box the packet, then queue it to be sent on the next server tick.

Examples found in repository?
examples/simple_server.rs (line 129)
60fn main() -> Result<()> {
61    // Begin hosting a TCP server
62    let mut server = Server::host("127.0.0.1", 7667, 32)?;
63    println!("Hosting on 127.0.0.1:7667...");
64
65    // We are going to keep track of the # of pings we receive from each client, and kick them
66    // after they have sent a certain amount.
67    let mut ping_counters: HashMap<Token, u32> = HashMap::new();
68
69    loop {
70        // Sleep for a lil bit so we don't hog the CPU
71        std::thread::sleep(std::time::Duration::from_millis(100));
72
73        // Run the network tick and process any events it generates
74        for event in server.tick().iter() {
75            match event {
76                ServerEvent::ClientConnected(token, addr) => {
77                    println!(
78                        "Client {} connected from {} ({}/{})",
79                        token.0,
80                        addr.ip(),
81                        server.num_connections(),
82                        server.connection_limit(),
83                    );
84                }
85                ServerEvent::ClientDisconnected(token) => {
86                    println!("Client {} disconnected.", token.0);
87                }
88                ServerEvent::ConnectionRejected(addr) => {
89                    println!(
90                        "Rejected connection from {} (Connection limit reached)",
91                        addr.ip(),
92                    );
93                }
94                ServerEvent::ReceivedPacket(token, byte_count) => {
95                    println!(
96                        "Received packet from client {} ({} bytes)",
97                        token.0, byte_count
98                    );
99                }
100                ServerEvent::SentPacket(token, byte_count) => {
101                    println!("Sent packet to client {} ({} bytes)", token.0, byte_count);
102                }
103                _ => eprintln!("Unhandled ServerEvent!"),
104            }
105        }
106
107        // Process incoming packets
108        for (token, packet) in server.drain_incoming_packets().iter() {
109            match packet.header.id {
110                0x00 => {
111                    let packet = PingPacket::deserialize(&packet.body);
112                    println!("Got ping from client {}: {}", token.0, packet.unwrap().msg);
113
114                    // Increment the ping counter for this client
115                    let counter = ping_counters.entry(*token).or_insert(0);
116                    *counter += 1;
117
118                    if *counter >= 5 {
119                        // Kick the client when they reach 5 pings.
120                        println!("Client {} sent 5 pings. Kicking them.", token.0);
121                        server.kick(*token)?;
122
123                        ping_counters.remove_entry(token);
124                    } else {
125                        // Otherwise just send a ping response (pong).
126                        let pong = PongPacket {
127                            msg: "Pong!".to_owned(),
128                        };
129                        server.send(PacketRecipient::Single(*token), pong);
130                    }
131                }
132                _ => eprintln!("Unhandled packet! id: {}", packet.header.id),
133            }
134        }
135    }
136
137    Ok(())
138}
Source

pub fn send_boxed( &mut self, recipient: PacketRecipient, packet_boxed: Box<dyn PacketBody>, )

Send a boxed packet. Similar to send, but this is moreuseful when you have a boxed packet already and don’t want to cast it to a concrete type before sending it.

Source

pub fn tick(&mut self) -> Vec<ServerEvent>

Runs a network tick, which sends/receives packets based on socket readiness, as well as accepts new connections.

Examples found in repository?
examples/simple_server.rs (line 74)
60fn main() -> Result<()> {
61    // Begin hosting a TCP server
62    let mut server = Server::host("127.0.0.1", 7667, 32)?;
63    println!("Hosting on 127.0.0.1:7667...");
64
65    // We are going to keep track of the # of pings we receive from each client, and kick them
66    // after they have sent a certain amount.
67    let mut ping_counters: HashMap<Token, u32> = HashMap::new();
68
69    loop {
70        // Sleep for a lil bit so we don't hog the CPU
71        std::thread::sleep(std::time::Duration::from_millis(100));
72
73        // Run the network tick and process any events it generates
74        for event in server.tick().iter() {
75            match event {
76                ServerEvent::ClientConnected(token, addr) => {
77                    println!(
78                        "Client {} connected from {} ({}/{})",
79                        token.0,
80                        addr.ip(),
81                        server.num_connections(),
82                        server.connection_limit(),
83                    );
84                }
85                ServerEvent::ClientDisconnected(token) => {
86                    println!("Client {} disconnected.", token.0);
87                }
88                ServerEvent::ConnectionRejected(addr) => {
89                    println!(
90                        "Rejected connection from {} (Connection limit reached)",
91                        addr.ip(),
92                    );
93                }
94                ServerEvent::ReceivedPacket(token, byte_count) => {
95                    println!(
96                        "Received packet from client {} ({} bytes)",
97                        token.0, byte_count
98                    );
99                }
100                ServerEvent::SentPacket(token, byte_count) => {
101                    println!("Sent packet to client {} ({} bytes)", token.0, byte_count);
102                }
103                _ => eprintln!("Unhandled ServerEvent!"),
104            }
105        }
106
107        // Process incoming packets
108        for (token, packet) in server.drain_incoming_packets().iter() {
109            match packet.header.id {
110                0x00 => {
111                    let packet = PingPacket::deserialize(&packet.body);
112                    println!("Got ping from client {}: {}", token.0, packet.unwrap().msg);
113
114                    // Increment the ping counter for this client
115                    let counter = ping_counters.entry(*token).or_insert(0);
116                    *counter += 1;
117
118                    if *counter >= 5 {
119                        // Kick the client when they reach 5 pings.
120                        println!("Client {} sent 5 pings. Kicking them.", token.0);
121                        server.kick(*token)?;
122
123                        ping_counters.remove_entry(token);
124                    } else {
125                        // Otherwise just send a ping response (pong).
126                        let pong = PongPacket {
127                            msg: "Pong!".to_owned(),
128                        };
129                        server.send(PacketRecipient::Single(*token), pong);
130                    }
131                }
132                _ => eprintln!("Unhandled packet! id: {}", packet.header.id),
133            }
134        }
135    }
136
137    Ok(())
138}

Auto Trait Implementations§

§

impl !Freeze for Server

§

impl !RefUnwindSafe for Server

§

impl Send for Server

§

impl Sync for Server

§

impl Unpin for Server

§

impl !UnwindSafe for Server

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.