import { fetchEventSource } from '@microsoft/fetch-event-source'; import type { EventSourceMessage } from '@microsoft/fetch-event-source'; import { useEnterpriseStore } from '@/stores/modules/enterprise'; import { glsWithCatch } from '@/utils/stroage'; const customHost = 'http://localhost:3000'; const DEFAULT_SSE_URL = `${customHost}/agent/input`; const SSE_HEADERS = { 'Content-Type': 'application/json', 'Cache-Control': 'no-cache', Connection: 'keep-alive', Accept: 'text/event-stream', }; interface SSEConfig { headers?: Record; method?: string; body?: any; handleMessage?: (data: any) => void; handleError?: (err: any) => number | null | undefined | void; handleClose?: () => void; handleOpen?: (response: Response) => Promise; } /** * 创建服务器发送事件(SSE)连接 * @param config SSE 配置 * @param url 可选的自定义 URL */ export default async (config: SSEConfig, url: string = DEFAULT_SSE_URL): Promise => { const { body = undefined, headers = {}, method = 'get', handleMessage, handleError, handleOpen, handleClose, } = config; const store = useEnterpriseStore(); fetchEventSource(url, { method, // credentials: 'include', headers: { ...SSE_HEADERS, Authorization: glsWithCatch('accessToken'), 'enterprise-id': store.enterpriseInfo?.id?.toString(), ...headers, }, body, openWhenHidden: true, // 用户切换到另一个页面后仍能保持SSE连接 onmessage(event: EventSourceMessage) { if (event.data) { try { const parsedData = JSON.parse(event.data); handleMessage?.({ ...event, data: parsedData }); } catch (error) { console.error('Error parsing SSE message:', error); handleError(new Error('Failed to parse SSE message')); } } }, onerror(error: Error) { // console.error('SSE error:', error); handleError?.(error); }, onclose() { // console.log('SSE connection closed'); handleClose?.(); }, async onopen(response: Response) { // console.log('onopen', response); handleOpen?.(response); }, }); };