1use std::time::Duration;
2
3use tokio_tungstenite::tungstenite::protocol::WebSocketConfig;
4
5use crate::{
6 WsIoServer,
7 config::WsIoServerConfig,
8 core::packet::{
9 codecs::WsIoPacketCodec,
10 transformers::WsIoPacketTransformer,
11 },
12 runtime::WsIoServerRuntime,
13};
14
15#[derive(Debug)]
22#[must_use]
23pub struct WsIoServerBuilder {
24 config: WsIoServerConfig,
25}
26
27impl WsIoServerBuilder {
28 pub(crate) fn new() -> Self {
29 Self {
30 config: WsIoServerConfig {
31 broadcast_concurrency_limit: 512,
32 http_request_upgrade_timeout: Duration::from_secs(3),
33 init_request_handler_timeout: Duration::from_secs(3),
34 init_response_handler_timeout: Duration::from_secs(3),
35 init_response_timeout: Duration::from_secs(5),
36 middleware_execution_timeout: Duration::from_secs(2),
37 on_close_handler_timeout: Duration::from_secs(2),
38 on_connect_handler_timeout: Duration::from_secs(3),
39 packet_codec: WsIoPacketCodec::Msgpack,
40 packet_transformer: WsIoPacketTransformer::default(),
41 request_path: "/ws.io".to_owned(),
42 websocket_config: WebSocketConfig::default()
43 .max_frame_size(Some(8 * 1024 * 1024))
44 .max_message_size(Some(16 * 1024 * 1024))
45 .max_write_buffer_size(2 * 1024 * 1024)
46 .read_buffer_size(8 * 1024)
47 .write_buffer_size(8 * 1024),
48 },
49 }
50 }
51
52 pub fn broadcast_concurrency_limit(mut self, broadcast_concurrency_limit: usize) -> Self {
58 self.config.broadcast_concurrency_limit = broadcast_concurrency_limit;
59 self
60 }
61
62 pub fn build(self) -> WsIoServer {
64 WsIoServer(WsIoServerRuntime::new(self.config))
65 }
66
67 pub fn http_request_upgrade_timeout(mut self, duration: Duration) -> Self {
73 self.config.http_request_upgrade_timeout = duration;
74 self
75 }
76
77 pub fn init_request_handler_timeout(mut self, duration: Duration) -> Self {
82 self.config.init_request_handler_timeout = duration;
83 self
84 }
85
86 pub fn init_response_handler_timeout(mut self, duration: Duration) -> Self {
91 self.config.init_response_handler_timeout = duration;
92 self
93 }
94
95 pub fn init_response_timeout(mut self, duration: Duration) -> Self {
100 self.config.init_response_timeout = duration;
101 self
102 }
103
104 pub fn middleware_execution_timeout(mut self, duration: Duration) -> Self {
109 self.config.middleware_execution_timeout = duration;
110 self
111 }
112
113 pub fn on_close_handler_timeout(mut self, duration: Duration) -> Self {
118 self.config.on_close_handler_timeout = duration;
119 self
120 }
121
122 pub fn on_connect_handler_timeout(mut self, duration: Duration) -> Self {
127 self.config.on_connect_handler_timeout = duration;
128 self
129 }
130
131 pub fn packet_codec(mut self, packet_codec: WsIoPacketCodec) -> Self {
136 self.config.packet_codec = packet_codec;
137 self
138 }
139
140 pub fn packet_transformer(mut self, packet_transformer: WsIoPacketTransformer) -> Self {
144 self.config.packet_transformer = packet_transformer;
145 self
146 }
147
148 pub fn request_path(mut self, request_path: impl AsRef<str>) -> Self {
154 request_path.as_ref().clone_into(&mut self.config.request_path);
155 self
156 }
157
158 pub fn websocket_config(mut self, websocket_config: WebSocketConfig) -> Self {
164 self.config.websocket_config = websocket_config;
165 self
166 }
167
168 pub fn websocket_config_mut<F: FnOnce(&mut WebSocketConfig)>(mut self, f: F) -> Self {
172 f(&mut self.config.websocket_config);
173 self
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use std::time::Duration;
180
181 use super::*;
182
183 #[test]
184 fn test_builder_configuration_chaining() {
185 let server = WsIoServer::builder()
186 .broadcast_concurrency_limit(1024)
187 .http_request_upgrade_timeout(Duration::from_millis(750))
188 .init_request_handler_timeout(Duration::from_secs(1))
189 .init_response_handler_timeout(Duration::from_secs(2))
190 .init_response_timeout(Duration::from_secs(3))
191 .middleware_execution_timeout(Duration::from_secs(4))
192 .on_close_handler_timeout(Duration::from_secs(5))
193 .on_connect_handler_timeout(Duration::from_secs(6))
194 .packet_codec(WsIoPacketCodec::Msgpack)
195 .request_path("/custom")
196 .websocket_config_mut(|config| {
197 *config = config.max_frame_size(Some(999));
198 })
199 .build();
200
201 let config = &server.0.config;
203 assert_eq!(config.broadcast_concurrency_limit, 1024);
204 assert_eq!(config.http_request_upgrade_timeout, Duration::from_millis(750));
205 assert_eq!(config.init_request_handler_timeout, Duration::from_secs(1));
206 assert_eq!(config.init_response_handler_timeout, Duration::from_secs(2));
207 assert_eq!(config.init_response_timeout, Duration::from_secs(3));
208 assert_eq!(config.middleware_execution_timeout, Duration::from_secs(4));
209 assert_eq!(config.on_close_handler_timeout, Duration::from_secs(5));
210 assert_eq!(config.on_connect_handler_timeout, Duration::from_secs(6));
211 assert!(matches!(config.packet_codec, WsIoPacketCodec::Msgpack));
212 assert_eq!(config.request_path, "/custom");
213 assert_eq!(config.websocket_config.max_frame_size, Some(999));
214 }
215
216 #[test]
217 fn test_builder_websocket_config_override() {
218 let config = WebSocketConfig::default().max_frame_size(Some(42));
219 let server = WsIoServer::builder().websocket_config(config).build();
220 assert_eq!(server.0.config.websocket_config.max_frame_size, Some(42));
221 }
222}