Skip to main content

flare_core/server/
config.rs

1//! 服务端配置模块
2
3use crate::common::compression::CompressionAlgorithm;
4use crate::common::config_types::{HeartbeatConfig, TlsConfig, TransportProtocol};
5use crate::common::device::DeviceConflictStrategy;
6use crate::common::encryption::EncryptionAlgorithm;
7use crate::common::protocol::SerializationFormat;
8use std::time::Duration;
9
10/// 服务端配置
11#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
12pub struct ServerConfig {
13    /// 监听地址(单个协议时使用,多协议时用作默认地址)
14    pub bind_address: String,
15    /// 传输协议(单个)
16    pub transport: TransportProtocol,
17    /// 传输协议列表(用于同时监听多个协议)
18    pub transports: Option<Vec<TransportProtocol>>,
19    /// 每个协议的独立地址配置(协议 -> 地址映射)
20    /// 如果设置了此映射,每个协议将使用对应的地址
21    pub protocol_addresses: Option<std::collections::HashMap<TransportProtocol, String>>,
22    /// 序列化格式(默认格式)
23    pub default_serialization_format: SerializationFormat,
24    /// 压缩算法(默认)
25    pub default_compression: CompressionAlgorithm,
26    /// 加密算法(默认)
27    pub default_encryption: EncryptionAlgorithm,
28    /// 最大连接数
29    pub max_connections: usize,
30    /// 握手超时时间
31    pub handshake_timeout: Duration,
32    /// 最大并发握手数
33    pub max_handshake_concurrency: usize,
34    /// 单次连接写入超时时间
35    pub write_timeout: Duration,
36    /// fanout 发送最大并发度
37    pub fanout_concurrency: usize,
38    /// 连接超时时间
39    pub connection_timeout: Duration,
40    /// 默认心跳配置(可以为每个连接配置不同的心跳)
41    pub default_heartbeat: HeartbeatConfig,
42    /// TLS 配置(用于 HTTPS/WSS/QUIC)
43    pub tls: TlsConfig,
44    /// 消息大小限制(字节)
45    pub max_message_size: usize,
46    /// 设备冲突策略(用于多端设备管理)
47    pub device_conflict_strategy: DeviceConflictStrategy,
48    /// 是否启用认证(如果启用,连接必须通过 token 验证才能收发消息)
49    pub auth_enabled: bool,
50    /// 认证超时时间(连接建立后,如果在此时间内未完成认证,连接将被关闭)
51    pub auth_timeout: Duration,
52}
53
54impl Default for ServerConfig {
55    fn default() -> Self {
56        Self {
57            bind_address: "0.0.0.0:8080".to_string(),
58            transport: TransportProtocol::WebSocket,
59            transports: None,
60            protocol_addresses: None,
61            default_serialization_format: SerializationFormat::Protobuf,
62            default_compression: CompressionAlgorithm::None,
63            default_encryption: EncryptionAlgorithm::None,
64            max_connections: 10000,
65            handshake_timeout: Duration::from_secs(10),
66            max_handshake_concurrency: 1024,
67            write_timeout: Duration::from_secs(10),
68            fanout_concurrency: 256,
69            connection_timeout: Duration::from_secs(300),
70            default_heartbeat: HeartbeatConfig::default(),
71            tls: TlsConfig::none(),
72            max_message_size: 10 * 1024 * 1024, // 10MB
73            device_conflict_strategy: DeviceConflictStrategy::default(),
74            auth_enabled: false,                   // 默认不启用认证
75            auth_timeout: Duration::from_secs(30), // 默认认证超时 30 秒
76        }
77    }
78}
79
80impl ServerConfig {
81    /// 创建新的服务端配置
82    pub fn new(bind_address: String) -> Self {
83        Self {
84            bind_address,
85            ..Default::default()
86        }
87    }
88
89    /// 使用 WebSocket 协议
90    pub fn websocket(mut self) -> Self {
91        self.transport = TransportProtocol::WebSocket;
92        self
93    }
94
95    /// 使用 QUIC 协议
96    pub fn quic(mut self) -> Self {
97        self.transport = TransportProtocol::QUIC;
98        self
99    }
100
101    /// 使用 TCP 协议
102    pub fn tcp(mut self) -> Self {
103        self.transport = TransportProtocol::TCP;
104        self
105    }
106
107    /// 设置默认序列化格式
108    pub fn with_format(mut self, format: SerializationFormat) -> Self {
109        self.default_serialization_format = format;
110        self
111    }
112
113    /// 设置默认压缩算法
114    pub fn with_compression(mut self, compression: CompressionAlgorithm) -> Self {
115        self.default_compression = compression;
116        self
117    }
118
119    /// 设置默认加密算法
120    pub fn with_encryption(mut self, encryption: EncryptionAlgorithm) -> Self {
121        self.default_encryption = encryption;
122        self
123    }
124
125    /// 设置最大连接数
126    pub fn with_max_connections(mut self, max: usize) -> Self {
127        self.max_connections = max;
128        self
129    }
130
131    /// 设置握手超时时间
132    pub fn with_handshake_timeout(mut self, timeout: Duration) -> Self {
133        self.handshake_timeout = timeout;
134        self
135    }
136
137    /// 设置最大并发握手数
138    pub fn with_max_handshake_concurrency(mut self, max: usize) -> Self {
139        self.max_handshake_concurrency = max.max(1);
140        self
141    }
142
143    /// 设置单次连接写入超时时间
144    pub fn with_write_timeout(mut self, timeout: Duration) -> Self {
145        self.write_timeout = timeout;
146        self
147    }
148
149    /// 设置 fanout 发送最大并发度
150    pub fn with_fanout_concurrency(mut self, max: usize) -> Self {
151        self.fanout_concurrency = max.max(1);
152        self
153    }
154
155    /// 启用多协议监听
156    pub fn with_protocols(mut self, protocols: Vec<TransportProtocol>) -> Self {
157        self.transports = Some(protocols);
158        self
159    }
160
161    /// 为特定协议设置监听地址
162    pub fn with_protocol_address(mut self, protocol: TransportProtocol, address: String) -> Self {
163        if self.protocol_addresses.is_none() {
164            self.protocol_addresses = Some(std::collections::HashMap::new());
165        }
166        if let Some(ref mut addresses) = self.protocol_addresses {
167            addresses.insert(protocol, address);
168        }
169        self
170    }
171
172    /// 批量设置协议地址映射
173    pub fn with_protocol_addresses(
174        mut self,
175        addresses: std::collections::HashMap<TransportProtocol, String>,
176    ) -> Self {
177        self.protocol_addresses = Some(addresses);
178        self
179    }
180
181    /// 获取指定协议的地址
182    pub fn get_protocol_address(&self, protocol: &TransportProtocol) -> String {
183        let endpoint = if let Some(ref addresses) = self.protocol_addresses
184            && let Some(addr) = addresses.get(protocol)
185        {
186            addr.as_str()
187        } else {
188            self.bind_address.as_str()
189        };
190
191        TransportProtocol::normalize_server_bind_address(endpoint)
192    }
193
194    /// 设置默认心跳配置
195    pub fn with_heartbeat(mut self, heartbeat: HeartbeatConfig) -> Self {
196        self.default_heartbeat = heartbeat;
197        self
198    }
199
200    /// 设置 TLS 配置
201    pub fn with_tls(mut self, tls: TlsConfig) -> Self {
202        self.tls = tls;
203        self
204    }
205
206    /// 设置连接超时
207    pub fn with_connection_timeout(mut self, timeout: Duration) -> Self {
208        self.connection_timeout = timeout;
209        self
210    }
211
212    /// 获取要使用的协议列表
213    pub fn get_protocols(&self) -> Vec<TransportProtocol> {
214        if let Some(ref protocols) = self.transports {
215            protocols.clone()
216        } else {
217            vec![self.transport]
218        }
219    }
220
221    /// 设置设备冲突策略
222    pub fn with_device_conflict_strategy(mut self, strategy: DeviceConflictStrategy) -> Self {
223        self.device_conflict_strategy = strategy;
224        self
225    }
226
227    /// 启用认证
228    ///
229    /// 启用后,所有连接必须通过 token 验证才能收发消息
230    pub fn enable_auth(mut self) -> Self {
231        self.auth_enabled = true;
232        self
233    }
234
235    /// 禁用认证(默认)
236    pub fn disable_auth(mut self) -> Self {
237        self.auth_enabled = false;
238        self
239    }
240
241    /// 设置认证超时时间
242    ///
243    /// 连接建立后,如果在此时间内未完成认证,连接将被关闭
244    /// 默认值为 30 秒
245    pub fn with_auth_timeout(mut self, timeout: Duration) -> Self {
246        self.auth_timeout = timeout;
247        self
248    }
249}
250
251#[cfg(test)]
252mod tests {
253    use super::*;
254
255    #[test]
256    fn default_connection_admission_limits_are_enabled() {
257        let config = ServerConfig::default();
258
259        assert_eq!(config.handshake_timeout, Duration::from_secs(10));
260        assert_eq!(config.max_handshake_concurrency, 1024);
261        assert_eq!(config.write_timeout, Duration::from_secs(10));
262        assert_eq!(config.fanout_concurrency, 256);
263    }
264
265    #[test]
266    fn connection_admission_limits_are_configurable() {
267        let config = ServerConfig::default()
268            .with_handshake_timeout(Duration::from_secs(3))
269            .with_max_handshake_concurrency(32)
270            .with_write_timeout(Duration::from_secs(2))
271            .with_fanout_concurrency(8);
272
273        assert_eq!(config.handshake_timeout, Duration::from_secs(3));
274        assert_eq!(config.max_handshake_concurrency, 32);
275        assert_eq!(config.write_timeout, Duration::from_secs(2));
276        assert_eq!(config.fanout_concurrency, 8);
277    }
278
279    #[test]
280    fn derives_bind_addresses_without_client_schemes() {
281        let config = ServerConfig::new("ws://0.0.0.0:8080".to_string());
282
283        assert_eq!(
284            config.get_protocol_address(&TransportProtocol::WebSocket),
285            "0.0.0.0:8080"
286        );
287        assert_eq!(
288            config.get_protocol_address(&TransportProtocol::QUIC),
289            "0.0.0.0:8080"
290        );
291        assert_eq!(
292            config.get_protocol_address(&TransportProtocol::TCP),
293            "0.0.0.0:8080"
294        );
295    }
296
297    #[test]
298    fn normalizes_explicit_protocol_bind_address() {
299        let config = ServerConfig::default()
300            .with_protocol_address(TransportProtocol::TCP, "tcp://127.0.0.1:19090".to_string());
301
302        assert_eq!(
303            config.get_protocol_address(&TransportProtocol::TCP),
304            "127.0.0.1:19090"
305        );
306    }
307}