From 0e562dd808424b41edefc3bad048d4810839a58d Mon Sep 17 00:00:00 2001 From: 15945162479 <15945162479@qq.com> Date: Sat, 13 Dec 2025 14:46:14 +0800 Subject: [PATCH] Add File --- src/elderly/hooks/useToastSSE.ts | 82 ++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/elderly/hooks/useToastSSE.ts diff --git a/src/elderly/hooks/useToastSSE.ts b/src/elderly/hooks/useToastSSE.ts new file mode 100644 index 0000000..4684510 --- /dev/null +++ b/src/elderly/hooks/useToastSSE.ts @@ -0,0 +1,82 @@ +/** + * SSE Toast通知Hook + * 通过Server-Sent Events接收实时Toast推送 + */ + +import { useEffect } from 'react'; + +export interface ToastData { + id: number; + type: 'success' | 'info' | 'calling'; + message: string; + duration: number; +} + +interface UseToastSSEOptions { + familyId: string; + onToast: (toast: ToastData) => void; +} + +export function useToastSSE({ familyId, onToast }: UseToastSSEOptions) { + useEffect(() => { + const sseUrl = `http://localhost:8000/api/elderly/toast/stream?family_id=${familyId}`; + let eventSource: EventSource | null = null; + let reconnectTimeout: NodeJS.Timeout | null = null; + + const connect = () => { + try { + console.log('[SSE Toast] 连接中...'); + eventSource = new EventSource(sseUrl); + + eventSource.onopen = () => { + console.log('[SSE Toast] 连接已建立'); + }; + + eventSource.onmessage = (event) => { + try { + const data = JSON.parse(event.data); + + // 忽略连接确认消息 + if (data.type === 'connected') { + console.log('[SSE Toast] 连接已确认'); + return; + } + + // 收到Toast通知 + console.log('[SSE Toast] 收到通知:', data); + onToast(data as ToastData); + } catch (err) { + console.error('[SSE Toast] 解析数据失败:', err); + } + }; + + eventSource.onerror = (error) => { + console.error('[SSE Toast] 连接错误:', error); + eventSource?.close(); + + // 5秒后重连 + reconnectTimeout = setTimeout(() => { + console.log('[SSE Toast] 尝试重新连接...'); + connect(); + }, 5000); + }; + } catch (error) { + console.error('[SSE Toast] 连接失败:', error); + } + }; + + // 建立连接 + connect(); + + // 清理 + return () => { + console.log('[SSE Toast] 清理连接'); + if (eventSource) { + eventSource.close(); + } + if (reconnectTimeout) { + clearTimeout(reconnectTimeout); + } + }; + }, [familyId, onToast]); +}