Skip to main content

flare_core/common/message/
handler.rs

1//! 消息处理器模块
2//!
3//! 使用观察者模式处理不同类型的消息
4
5use crate::common::error::Result;
6use crate::common::protocol::flare::core::commands::{
7    notification_command::Type as NotificationType, payload_command::Type as PayloadType,
8    system_command::Type as SystemType,
9};
10use crate::common::protocol::{
11    CustomCommand, Frame, NotificationCommand, PayloadCommand, SystemCommand,
12};
13use std::sync::Arc;
14use std::sync::Mutex;
15
16/// 消息事件类型
17#[derive(Debug, Clone)]
18pub enum MessageEvent {
19    /// 系统命令事件
20    System {
21        frame: Frame,
22        command: SystemCommand,
23        command_type: SystemType,
24    },
25    /// 载荷命令事件
26    Message {
27        frame: Frame,
28        command: PayloadCommand,
29        command_type: PayloadType,
30    },
31    /// 通知命令事件
32    Notification {
33        frame: Frame,
34        command: NotificationCommand,
35        command_type: NotificationType,
36    },
37    /// 自定义命令事件
38    Custom {
39        frame: Frame,
40        command: CustomCommand,
41    },
42    /// 未知或无效的命令
43    Unknown(Frame),
44}
45
46/// 消息观察者 trait
47///
48/// 实现此 trait 以处理不同类型的消息事件
49pub trait MessageObserver: Send + Sync {
50    /// 处理系统命令
51    fn on_system_command(
52        &self,
53        frame: &Frame,
54        command: &SystemCommand,
55        command_type: SystemType,
56    ) -> Result<()> {
57        let _ = (frame, command, command_type);
58        Ok(())
59    }
60
61    /// 处理载荷命令
62    fn on_message_command(
63        &self,
64        frame: &Frame,
65        command: &PayloadCommand,
66        command_type: PayloadType,
67    ) -> Result<()> {
68        let _ = (frame, command, command_type);
69        Ok(())
70    }
71
72    /// 处理通知命令
73    fn on_notification_command(
74        &self,
75        frame: &Frame,
76        command: &NotificationCommand,
77        command_type: NotificationType,
78    ) -> Result<()> {
79        let _ = (frame, command, command_type);
80        Ok(())
81    }
82
83    /// 处理自定义命令
84    fn on_custom_command(&self, frame: &Frame, command: &CustomCommand) -> Result<()> {
85        let _ = (frame, command);
86        Ok(())
87    }
88
89    /// 处理未知命令
90    fn on_unknown_command(&self, frame: &Frame) -> Result<()> {
91        let _ = frame;
92        Ok(())
93    }
94}
95
96/// 线程安全的消息观察者类型别名
97pub type ArcMessageObserver = Arc<dyn MessageObserver>;
98
99/// 消息处理器
100///
101/// 使用观察者模式处理消息,支持注册多个观察者
102pub struct MessageHandler {
103    observers: Arc<Mutex<Vec<ArcMessageObserver>>>,
104}
105
106impl MessageHandler {
107    /// 创建新的消息处理器
108    pub fn new() -> Self {
109        Self {
110            observers: Arc::new(Mutex::new(Vec::new())),
111        }
112    }
113
114    /// 添加观察者
115    pub fn add_observer(&self, observer: ArcMessageObserver) {
116        if let Ok(mut observers) = self.observers.lock() {
117            observers.push(observer);
118        }
119    }
120
121    /// 移除观察者
122    pub fn remove_observer(&self, observer: ArcMessageObserver) {
123        if let Ok(mut observers) = self.observers.lock() {
124            observers.retain(|o| !Arc::ptr_eq(o, &observer));
125        }
126    }
127
128    /// 处理消息 Frame
129    ///
130    /// 解析 Frame 并分发到相应的观察者
131    pub fn handle_frame(&self, frame: Frame) -> Result<MessageEvent> {
132        let event = Self::parse_frame_to_event(frame.clone())?;
133
134        let observers = self.observers.lock().map_err(|_| {
135            crate::common::error::FlareError::general_error("Failed to lock observers")
136        })?;
137
138        match &event {
139            MessageEvent::System {
140                frame,
141                command,
142                command_type,
143            } => {
144                for observer in observers.iter() {
145                    if let Err(e) = observer.on_system_command(frame, command, *command_type) {
146                        // 记录错误但继续处理其他观察者
147                        eprintln!("Observer error handling system command: {:?}", e);
148                    }
149                }
150            }
151            MessageEvent::Message {
152                frame,
153                command,
154                command_type,
155            } => {
156                for observer in observers.iter() {
157                    if let Err(e) = observer.on_message_command(frame, command, *command_type) {
158                        eprintln!("Observer error handling message command: {:?}", e);
159                    }
160                }
161            }
162            MessageEvent::Notification {
163                frame,
164                command,
165                command_type,
166            } => {
167                for observer in observers.iter() {
168                    if let Err(e) = observer.on_notification_command(frame, command, *command_type)
169                    {
170                        eprintln!("Observer error handling notification command: {:?}", e);
171                    }
172                }
173            }
174            MessageEvent::Custom { frame, command } => {
175                for observer in observers.iter() {
176                    if let Err(e) = observer.on_custom_command(frame, command) {
177                        eprintln!("Observer error handling custom command: {:?}", e);
178                    }
179                }
180            }
181            MessageEvent::Unknown(frame) => {
182                for observer in observers.iter() {
183                    if let Err(e) = observer.on_unknown_command(frame) {
184                        eprintln!("Observer error handling unknown command: {:?}", e);
185                    }
186                }
187            }
188        }
189
190        Ok(event)
191    }
192
193    /// 将 Frame 解析为 MessageEvent
194    fn parse_frame_to_event(frame: Frame) -> Result<MessageEvent> {
195        let command = frame.command.as_ref().ok_or_else(|| {
196            crate::common::error::FlareError::protocol_error("Frame missing command")
197        })?;
198
199        match &command.r#type {
200            Some(crate::common::protocol::flare::core::commands::command::Type::System(
201                system_cmd,
202            )) => {
203                // 直接从 i32 转换为枚举(使用 unsafe,因为 prost 生成的枚举是 repr(i32))
204                let command_type = match system_cmd.r#type {
205                    0 => SystemType::Unspecified,
206                    1 => SystemType::Connect,
207                    2 => SystemType::ConnectAck,
208                    3 => SystemType::Close,
209                    4 => SystemType::Ping,
210                    5 => SystemType::Pong,
211                    6 => SystemType::Error,
212                    7 => SystemType::Event,
213                    8 => SystemType::Auth,
214                    9 => SystemType::AuthAck,
215                    _ => {
216                        return Err(crate::common::error::FlareError::protocol_error(
217                            "Invalid system command type",
218                        ));
219                    }
220                };
221                Ok(MessageEvent::System {
222                    frame: frame.clone(),
223                    command: system_cmd.clone(),
224                    command_type,
225                })
226            }
227            Some(crate::common::protocol::flare::core::commands::command::Type::Payload(
228                msg_cmd,
229            )) => {
230                let command_type = match msg_cmd.r#type {
231                    0 => PayloadType::Unspecified,
232                    1 => PayloadType::Message,
233                    2 => PayloadType::Event,
234                    3 => PayloadType::Ack,
235                    4 => PayloadType::Data,
236                    _ => {
237                        return Err(crate::common::error::FlareError::protocol_error(
238                            "Invalid payload command type",
239                        ));
240                    }
241                };
242                Ok(MessageEvent::Message {
243                    frame: frame.clone(),
244                    command: msg_cmd.clone(),
245                    command_type,
246                })
247            }
248            Some(crate::common::protocol::flare::core::commands::command::Type::Notification(
249                notif_cmd,
250            )) => {
251                let command_type = match notif_cmd.r#type {
252                    0 => NotificationType::System,
253                    1 => NotificationType::Broadcast,
254                    2 => NotificationType::Alert,
255                    3 => NotificationType::User,
256                    4 => NotificationType::Connection,
257                    _ => {
258                        return Err(crate::common::error::FlareError::protocol_error(
259                            "Invalid notification command type",
260                        ));
261                    }
262                };
263                Ok(MessageEvent::Notification {
264                    frame: frame.clone(),
265                    command: notif_cmd.clone(),
266                    command_type,
267                })
268            }
269            Some(crate::common::protocol::flare::core::commands::command::Type::Custom(
270                custom_cmd,
271            )) => Ok(MessageEvent::Custom {
272                frame: frame.clone(),
273                command: custom_cmd.clone(),
274            }),
275            None => Ok(MessageEvent::Unknown(frame)),
276        }
277    }
278
279    /// 获取观察者数量
280    pub fn observer_count(&self) -> usize {
281        self.observers.lock().map(|obs| obs.len()).unwrap_or(0)
282    }
283}
284
285impl Default for MessageHandler {
286    fn default() -> Self {
287        Self::new()
288    }
289}
290
291#[cfg(test)]
292mod tests {
293    use super::*;
294    use crate::common::protocol::{Command, FrameBuilder, ping};
295
296    struct TestObserver {
297        system_count: Arc<Mutex<usize>>,
298    }
299
300    impl MessageObserver for TestObserver {
301        fn on_system_command(
302            &self,
303            _frame: &Frame,
304            _command: &SystemCommand,
305            _command_type: SystemType,
306        ) -> Result<()> {
307            let mut count = self.system_count.lock().unwrap();
308            *count += 1;
309            Ok(())
310        }
311    }
312
313    #[test]
314    fn test_message_handler() {
315        let handler = MessageHandler::new();
316        let observer = Arc::new(TestObserver {
317            system_count: Arc::new(Mutex::new(0)),
318        });
319        handler.add_observer(observer.clone());
320
321        let frame = FrameBuilder::new()
322            .with_command(Command {
323                r#type: Some(crate::common::protocol::command::Type::System(ping())),
324            })
325            .build();
326
327        let event = handler.handle_frame(frame).unwrap();
328        match event {
329            MessageEvent::System { .. } => {
330                let count = observer.system_count.lock().unwrap();
331                assert_eq!(*count, 1);
332            }
333            _ => panic!("Expected System event"),
334        }
335    }
336}