pub struct Server<const BUFFER_SIZE: usize> { /* private fields */ }Implementations§
Source§impl<const BUFFER_SIZE: usize> Server<BUFFER_SIZE>
impl<const BUFFER_SIZE: usize> Server<BUFFER_SIZE>
Sourcepub fn bind(
address: SocketAddr,
read_timeout: Duration,
) -> Result<Self, ServerError>
pub fn bind( address: SocketAddr, read_timeout: Duration, ) -> Result<Self, ServerError>
Examples found in repository?
examples/simple.rs (line 91)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Sourcepub fn address(&self) -> SocketAddr
pub fn address(&self) -> SocketAddr
Returns the address that the server is listening on this is the address that the server is bound to
Sourcepub fn get_client_info(&self, client_id: ClientID) -> Option<ServerClientInfo>
pub fn get_client_info(&self, client_id: ClientID) -> Option<ServerClientInfo>
Return client information
Examples found in repository?
examples/simple.rs (line 119)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Sourcepub fn is_valid_client(&self, client_id: ClientID) -> bool
pub fn is_valid_client(&self, client_id: ClientID) -> bool
Check whether or not a client id matches a valid connected client
Examples found in repository?
examples/simple.rs (line 137)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Sourcepub fn clients(&self) -> Vec<ClientID>
pub fn clients(&self) -> Vec<ClientID>
Return all the connected client IDs
Examples found in repository?
examples/simple.rs (line 134)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Sourcepub fn is_running(&self) -> bool
pub fn is_running(&self) -> bool
Returns true if the server is still running (not stopped)
Examples found in repository?
examples/simple.rs (line 96)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Sourcepub fn stop(&mut self) -> Result<(), ServerError>
pub fn stop(&mut self) -> Result<(), ServerError>
Stops the server
Examples found in repository?
examples/simple.rs (line 166)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Sourcepub fn send(
&self,
client_id: ClientID,
protocol: Protocol,
data: &[u8],
) -> Result<(), ServerError>
pub fn send( &self, client_id: ClientID, protocol: Protocol, data: &[u8], ) -> Result<(), ServerError>
Send data to a client
Examples found in repository?
examples/simple.rs (lines 122-130)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Sourcepub fn recv(
&self,
client_id: ClientID,
protocol: Protocol,
) -> Result<Option<([u8; BUFFER_SIZE], usize)>, ServerError>
pub fn recv( &self, client_id: ClientID, protocol: Protocol, ) -> Result<Option<([u8; BUFFER_SIZE], usize)>, ServerError>
Receive data from a client and also return the size
Examples found in repository?
examples/simple.rs (line 148)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Sourcepub fn flush(&self) -> Result<(), ServerError>
pub fn flush(&self) -> Result<(), ServerError>
Flush all queued tasks
Examples found in repository?
examples/simple.rs (line 105)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Sourcepub fn kick(&mut self, client_id: ClientID) -> Result<(), ServerError>
pub fn kick(&mut self, client_id: ClientID) -> Result<(), ServerError>
Kick a client
Examples found in repository?
examples/simple.rs (line 162)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Sourcepub fn new_clients(&mut self) -> Result<Vec<ClientID>, ServerError>
pub fn new_clients(&mut self) -> Result<Vec<ClientID>, ServerError>
Returns new clients’ IDs
Examples found in repository?
examples/simple.rs (line 113)
87fn spawn_server(protocol: Protocol) -> Result<(), ServerError> {
88 println!("Starting server...");
89
90 // Creating the server and binding it to a local address to listen on.
91 let mut server: Server<BUFFER_SIZE> = Server::bind(SERVER_ADDRESS, READ_TIMEOUT)?;
92
93 // Server loop.
94 loop {
95 // Check to see if the server is still running.
96 if server.is_running() == false {
97 break;
98 }
99
100 // Flush the server.
101 //
102 // I just now, as I was writing this comment, realized
103 // that you are flushing using a handle to the underlying
104 // TCP stream! Ha! Flushing... using a handle! :D
105 server.flush()?;
106
107 // There is a separate thread that accepts incoming client
108 // connections, and this function simply gets a list of
109 // any client IDs for clients that joined since the last call
110 // of this function. If this function was never called, it
111 // will return all clients, which means this function is guarenteed
112 // to return all client IDs through out the runtime of the program.
113 let new_clients = server.new_clients()?;
114
115 // Just iterating through all the new clients and welcoming them.
116 for client_id in new_clients {
117 // This should always return Some(...) since the client ID
118 // is guarenteed to be a valid client's ID.
119 let client_info = server.get_client_info(client_id).unwrap();
120
121 println!("New client {}: {}", client_id.id, client_info.client_address);
122 server.send(
123 client_id,
124 protocol,
125 format!(
126 "Hello client #{}! Your address is: {}",
127 client_id.id,
128 client_info.client_address,
129 ).as_bytes(),
130 )?;
131 }
132
133 // Iterate through every client connected to the server.
134 for client_id in server.clients() {
135 // If this returns false, this is most likely because the
136 // server kicked this client in a previous iteration.
137 if server.is_valid_client(client_id) == false {
138 println!("Invalid client, skipping... (#{})", client_id.id);
139
140 continue;
141 }
142
143 // Unlike the vanilla implementations of TCP and UDP in the standard libraries
144 // of programming languages, this library's recv() function is non-blocking,
145 // so it returns either data or nothing.
146 // The read timeout (discussed earlier) is for the blocking recv() call in the
147 // reading thread so the reading thread doesn't get stuck.
148 if let Some((message_raw, message_size)) = server.recv(client_id, protocol)? {
149 // The reason that a slice of the raw bytes as opposed to the whole
150 // thing is being used is because the string will actually have a lot
151 // of termination characters at the end since the raw bytes message
152 // is the same size as the BUFFER_SIZE constant. So by passing a slice,
153 // this string will only be made with bytes that were received as opposed
154 // to the entire buffer.
155 let message = String::from_utf8_lossy(&message_raw[..message_size]).to_string();
156
157 println!("<Client #{}> {}", client_id.id, message);
158
159 match message.as_str() {
160 "quit" => {
161 println!("Kicking client #{}...", client_id.id);
162 server.kick(client_id)?;
163 },
164 "stop" => {
165 println!("Stopping server...");
166 server.stop()?;
167 },
168 "protocol" => {
169 println!("Protocol: {:?}", protocol);
170 },
171 _ => (),
172 };
173 }
174 }
175 }
176
177 Ok(())
178}Trait Implementations§
Auto Trait Implementations§
impl<const BUFFER_SIZE: usize> Freeze for Server<BUFFER_SIZE>
impl<const BUFFER_SIZE: usize> RefUnwindSafe for Server<BUFFER_SIZE>
impl<const BUFFER_SIZE: usize> Send for Server<BUFFER_SIZE>
impl<const BUFFER_SIZE: usize> Sync for Server<BUFFER_SIZE>
impl<const BUFFER_SIZE: usize> Unpin for Server<BUFFER_SIZE>
impl<const BUFFER_SIZE: usize> UnwindSafe for Server<BUFFER_SIZE>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more