Files
qinqinghuisheng/src/elderly/hooks/useToastSSE.ts

83 lines
2.1 KiB
TypeScript
Raw Normal View History

2025-12-13 14:46:14 +08:00
/**
* 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]);
}