1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use std::{
fmt::{
Debug as FmtDebug,
Formatter,
Result as FmtResult,
},
pin::Pin,
sync::Arc,
time::Duration,
};
use anyhow::Result;
use tokio_tungstenite::tungstenite::protocol::WebSocketConfig;
use crate::{
connection::WsIoServerConnection,
core::{
packet::codecs::WsIoPacketCodec,
types::{
ArcAsyncUnaryResultHandler,
BoxAsyncUnaryResultHandler,
},
},
};
// Types
type InitRequestHandler = Box<
dyn for<'a> Fn(
Arc<WsIoServerConnection>,
&'a WsIoPacketCodec,
) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>>> + Send + 'a>>
+ Send
+ Sync
+ 'static,
>;
type InitResponseHandler = Box<
dyn for<'a> Fn(
Arc<WsIoServerConnection>,
Option<&'a [u8]>,
&'a WsIoPacketCodec,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>>
+ Send
+ Sync
+ 'static,
>;
// Structs
pub(crate) struct WsIoServerNamespaceConfig {
/// Maximum number of broadcast send operations this namespace runs at once.
///
/// Inherited from `WsIoServerConfig` when the namespace builder is created and
/// overridable per namespace. This is passed to
/// `StreamExt::for_each_concurrent`, where `0` is treated as no concurrency
/// limit.
pub(crate) broadcast_concurrency_limit: usize,
/// Maximum duration allowed for a matched HTTP request to finish the
/// WebSocket upgrade for this namespace.
pub(super) http_request_upgrade_timeout: Duration,
/// Optional server-side init-request handler for this namespace.
///
/// When present, it runs during connection setup and may return optional data
/// that is encoded with `packet_codec` and sent to the client as the init
/// packet payload.
pub(crate) init_request_handler: Option<InitRequestHandler>,
/// Maximum duration allowed for `init_request_handler` to execute.
pub(crate) init_request_handler_timeout: Duration,
/// Optional server-side init-response handler for this namespace.
///
/// When present, it receives the optional client response payload after
/// decoding and runs before middleware/on-connect processing continues.
pub(crate) init_response_handler: Option<InitResponseHandler>,
/// Maximum duration allowed for `init_response_handler` to execute.
pub(crate) init_response_handler_timeout: Duration,
/// Maximum duration to wait for the client to send its init-response packet.
pub(crate) init_response_timeout: Duration,
/// Optional namespace middleware run during connection setup.
///
/// Middleware runs after init-response handling and before the on-connect
/// handler. Returning an error rejects/aborts the connection setup.
pub(crate) middleware: Option<BoxAsyncUnaryResultHandler<WsIoServerConnection>>,
/// Maximum duration allowed for `middleware` execution.
pub(crate) middleware_execution_timeout: Duration,
/// Maximum duration allowed for a connection's on-close handler to execute.
pub(crate) on_close_handler_timeout: Duration,
/// Optional namespace on-connect handler.
///
/// Runs during setup after middleware and before the ready packet is sent.
pub(crate) on_connect_handler: Option<BoxAsyncUnaryResultHandler<WsIoServerConnection>>,
/// Maximum duration allowed for `on_connect_handler` execution.
pub(crate) on_connect_handler_timeout: Duration,
/// Optional namespace on-ready handler.
///
/// Runs asynchronously after the connection has completed setup and has been
/// marked ready. It is spawned instead of being awaited in the setup path.
pub(crate) on_ready_handler: Option<ArcAsyncUnaryResultHandler<WsIoServerConnection>>,
/// Packet codec used by this namespace for protocol packets and init data.
pub(crate) packet_codec: WsIoPacketCodec,
/// Namespace path used for routing clients from the `namespace` query
/// parameter after the server request path is matched.
pub(super) path: String,
/// Tungstenite WebSocket transport limits and buffer sizes for this namespace.
///
/// The namespace receives a copy of the server-level config when the builder is
/// created, then may override it independently. It is also used to size
/// internal connection channels from the configured max-write/write-buffer
/// ratio.
pub(crate) websocket_config: WebSocketConfig,
}
impl FmtDebug for WsIoServerNamespaceConfig {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("WsIoServerNamespaceConfig")
.field("path", &self.path)
.field("broadcast_concurrency_limit", &self.broadcast_concurrency_limit)
.field("http_request_upgrade_timeout", &self.http_request_upgrade_timeout)
.field(
"init_request_handler",
&self.init_request_handler.as_ref().map(|_| "<handler>"),
)
.field("init_request_handler_timeout", &self.init_request_handler_timeout)
.field(
"init_response_handler",
&self.init_response_handler.as_ref().map(|_| "<handler>"),
)
.field("init_response_handler_timeout", &self.init_response_handler_timeout)
.field("init_response_timeout", &self.init_response_timeout)
.field("middleware", &self.middleware.as_ref().map(|_| "<handler>"))
.field("middleware_execution_timeout", &self.middleware_execution_timeout)
.field("on_close_handler_timeout", &self.on_close_handler_timeout)
.field(
"on_connect_handler",
&self.on_connect_handler.as_ref().map(|_| "<handler>"),
)
.field("on_connect_handler_timeout", &self.on_connect_handler_timeout)
.field("on_ready_handler", &self.on_ready_handler.as_ref().map(|_| "<handler>"))
.field("packet_codec", &self.packet_codec)
.field("websocket_config", &self.websocket_config)
.finish()
}
}