engineioxide/config.rs
1//! ## Configuration for the engine.io engine & transports
2//! #### Example :
3//! ```rust
4//! # use bytes::Bytes;
5//! # use engineioxide::config::EngineIoConfig;
6//! # use engineioxide::service::EngineIoService;
7//! # use engineioxide::handler::EngineIoHandler;
8//! # use std::time::Duration;
9//! # use engineioxide::{Socket, DisconnectReason, Str};
10//! # use std::sync::Arc;
11//! #[derive(Debug, Clone)]
12//! struct MyHandler;
13//!
14//! impl EngineIoHandler for MyHandler {
15//! type Data = ();
16//! fn on_connect(self: Arc<Self>, socket: Arc<Socket<()>>) { }
17//! fn on_disconnect(&self, socket: Arc<Socket<()>>, reason: DisconnectReason) { }
18//! fn on_message(self: &Arc<Self>, msg: Str, socket: Arc<Socket<()>>) { }
19//! fn on_binary(self: &Arc<Self>, data: Bytes, socket: Arc<Socket<()>>) { }
20//! }
21//!
22//! let config = EngineIoConfig::builder()
23//! .ping_interval(Duration::from_millis(300)) // Set the ping_interval to 300ms
24//! .ping_timeout(Duration::from_millis(200)) // Set the ping timeout to 200ms
25//! .max_payload(1e6 as u64) // Set the max payload to a given size
26//! .max_buffer_size(1024) // Set a custom buffer size
27//! .build();
28//!
29//! // Create an engine io service with a custom config
30//! let svc = EngineIoService::with_config(Arc::new(MyHandler), config);
31//! ```
32
33use std::{borrow::Cow, time::Duration};
34
35use crate::service::TransportType;
36
37/// Configuration for the engine.io engine & transports
38#[derive(Debug, Clone)]
39pub struct EngineIoConfig {
40 /// The path to listen for engine.io requests on.
41 /// Defaults to "/engine.io".
42 pub req_path: Cow<'static, str>,
43
44 /// The interval at which the server will send a ping packet to the client.
45 /// Defaults to 25 seconds.
46 pub ping_interval: Duration,
47
48 /// The amount of time the server will wait for a ping response from the client before closing the connection.
49 /// Defaults to 20 seconds.
50 pub ping_timeout: Duration,
51
52 /// The maximum number of packets that can be buffered per connection before being emitted to the client.
53 ///
54 /// If the buffer if full the `emit()` method will return an error
55 ///
56 /// Defaults to 128 packets
57 pub max_buffer_size: usize,
58
59 /// The maximum number of bytes that can be received per http request.
60 /// Defaults to 100KB.
61 pub max_payload: u64,
62
63 /// The size of the read buffer for the websocket transport.
64 /// You can tweak this value depending on your use case. By default it is set to 4KiB.
65 ///
66 /// Setting it to a higher value will improve performance on heavy read scenarios
67 /// but will consume more memory.
68 pub ws_read_buffer_size: usize,
69
70 /// Allowed transports on this server
71 /// It is represented as a bitfield to allow to combine any number of transports easily
72 pub transports: u8,
73}
74
75impl Default for EngineIoConfig {
76 fn default() -> Self {
77 Self {
78 req_path: "/engine.io".into(),
79 ping_interval: Duration::from_millis(25000),
80 ping_timeout: Duration::from_millis(20000),
81 max_buffer_size: 128,
82 max_payload: 1e5 as u64, // 100kb
83 ws_read_buffer_size: 4096,
84 transports: TransportType::Polling as u8 | TransportType::Websocket as u8,
85 }
86 }
87}
88
89impl EngineIoConfig {
90 /// Create a new builder with a default config
91 pub fn builder() -> EngineIoConfigBuilder {
92 EngineIoConfigBuilder::new()
93 }
94
95 /// Check if a [`TransportType`] is enabled in the [`EngineIoConfig`]
96 #[inline(always)]
97 pub fn allowed_transport(&self, transport: TransportType) -> bool {
98 self.transports & transport as u8 == transport as u8
99 }
100}
101
102/// Builder for [`EngineIoConfig`]
103pub struct EngineIoConfigBuilder {
104 config: EngineIoConfig,
105}
106
107impl EngineIoConfigBuilder {
108 /// Create a new builder with a default config
109 pub fn new() -> Self {
110 Self {
111 config: EngineIoConfig::default(),
112 }
113 }
114
115 /// The path to listen for engine.io requests on.
116 /// Defaults to "/engine.io".
117 pub fn req_path(mut self, req_path: impl Into<Cow<'static, str>>) -> Self {
118 self.config.req_path = req_path.into();
119 self
120 }
121
122 /// The interval at which the server will send a ping packet to the client.
123 /// Defaults to 25 seconds.
124 pub fn ping_interval(mut self, ping_interval: Duration) -> Self {
125 self.config.ping_interval = ping_interval;
126 self
127 }
128
129 // The amount of time the server will wait for a ping response from the client before closing the connection.
130 /// Defaults to 20 seconds.
131 pub fn ping_timeout(mut self, ping_timeout: Duration) -> Self {
132 self.config.ping_timeout = ping_timeout;
133 self
134 }
135
136 /// The maximum number of packets that can be buffered per connection before being emitted to the client.
137 ///
138 /// If the buffer if full the `emit()` method will return an error
139 /// ```
140 /// # use bytes::Bytes;
141 /// # use engineioxide::{
142 /// Str,
143 /// layer::EngineIoLayer,
144 /// handler::EngineIoHandler,
145 /// socket::{Socket, DisconnectReason},
146 /// };
147 /// # use std::sync::Arc;
148 /// #[derive(Debug, Clone)]
149 /// struct MyHandler;
150 ///
151 /// impl EngineIoHandler for MyHandler {
152 ///
153 /// type Data = ();
154 /// fn on_connect(self: Arc<Self>, socket: Arc<Socket<()>>) {
155 /// println!("socket connect {}", socket.id);
156 /// }
157 /// fn on_disconnect(&self, socket: Arc<Socket<()>>, reason: DisconnectReason) {
158 /// println!("socket disconnect {}", socket.id);
159 /// }
160 ///
161 /// fn on_message(self: &Arc<Self>, msg: Str, socket: Arc<Socket<()>>) {
162 /// println!("Ping pong message {:?}", msg);
163 /// socket.emit(msg).unwrap();
164 /// }
165 ///
166 /// fn on_binary(self: &Arc<Self>, data: Bytes, socket: Arc<Socket<()>>) {
167 /// println!("Ping pong binary message {:?}", data);
168 /// socket.emit_binary(data).unwrap();
169 /// }
170 /// }
171 /// ```
172 pub fn max_buffer_size(mut self, max_buffer_size: usize) -> Self {
173 self.config.max_buffer_size = max_buffer_size;
174 self
175 }
176
177 /// The maximum number of bytes that can be received per http request.
178 /// Defaults to 100kb.
179 pub fn max_payload(mut self, max_payload: u64) -> Self {
180 self.config.max_payload = max_payload;
181 self
182 }
183
184 /// The size of the read buffer for the websocket transport.
185 /// You can tweak this value depending on your use case. Defaults to 4KiB.
186 ///
187 /// Setting it to a higher value will improve performance on heavy read scenarios
188 /// but will consume more memory.
189 pub fn ws_read_buffer_size(mut self, ws_read_buffer_size: usize) -> Self {
190 self.config.ws_read_buffer_size = ws_read_buffer_size;
191 self
192 }
193
194 /// Allowed transports on this server
195 ///
196 /// The `transports` array should have a size of 1 or 2
197 ///
198 /// Defaults to :
199 /// `[TransportType::Polling, TransportType::Websocket]`
200 pub fn transports<const N: usize>(mut self, transports: [TransportType; N]) -> Self {
201 assert!(N > 0 && N <= 2);
202 self.config.transports = 0;
203 for transport in transports {
204 self.config.transports |= transport as u8;
205 }
206 self
207 }
208
209 /// Build the config
210 pub fn build(self) -> EngineIoConfig {
211 self.config
212 }
213}
214impl Default for EngineIoConfigBuilder {
215 fn default() -> Self {
216 Self::new()
217 }
218}
219
220#[cfg(test)]
221mod tests {
222 use super::*;
223
224 #[test]
225 pub fn config_transports() {
226 let conf = EngineIoConfig::builder()
227 .transports([TransportType::Polling])
228 .build();
229 assert!(conf.allowed_transport(TransportType::Polling));
230 assert!(!conf.allowed_transport(TransportType::Websocket));
231
232 let conf = EngineIoConfig::builder()
233 .transports([TransportType::Websocket])
234 .build();
235 assert!(conf.allowed_transport(TransportType::Websocket));
236 assert!(!conf.allowed_transport(TransportType::Polling));
237 let conf = EngineIoConfig::builder()
238 .transports([TransportType::Polling, TransportType::Websocket])
239 .build();
240 assert!(conf.allowed_transport(TransportType::Polling));
241 assert!(conf.allowed_transport(TransportType::Websocket));
242 }
243}