Files
lingji-work-fe/src/utils/querySSE.ts

90 lines
2.5 KiB
TypeScript
Raw Normal View History

2025-08-25 11:49:58 +08:00
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';
import { BASE_PYTHON_URL } from '@/api/all/chat';
2025-08-28 14:58:58 +08:00
import { genRandomId } from '@/utils/tools';
2025-08-25 11:49:58 +08:00
const DEFAULT_SSE_URL = `${BASE_PYTHON_URL}/api/agent/runs`;
2025-08-25 11:49:58 +08:00
const SSE_HEADERS = {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
Accept: 'text/event-stream',
};
interface SSEConfig {
headers?: Record<string, string | number>;
method?: string;
body?: any;
handleMessage?: (data: any) => void;
handleError?: (err: any) => number | null | undefined | void;
handleClose?: () => void;
handleOpen?: (response: Response) => void;
2025-08-25 11:49:58 +08:00
}
/**
* SSE
* @param config SSE
* @param url URL
* @returns abort方法的对象SSE连接
2025-08-25 11:49:58 +08:00
*/
export default async (config: SSEConfig, url: string = DEFAULT_SSE_URL): Promise<{ abort: () => void }> => {
2025-08-25 11:49:58 +08:00
const {
body = undefined,
headers = {},
method = 'post',
2025-08-25 11:49:58 +08:00
handleMessage,
handleError,
handleOpen,
handleClose,
} = config;
const store = useEnterpriseStore();
// 创建AbortController实例用于中断请求
const abortController = new AbortController();
2025-08-25 11:49:58 +08:00
fetchEventSource(url, {
method,
// credentials: 'include',
headers: {
...SSE_HEADERS,
Authorization: glsWithCatch('accessToken'),
'enterprise-id': store.enterpriseInfo?.id?.toString(),
2025-09-01 14:44:01 +08:00
requestid: genRandomId(),
2025-08-25 11:49:58 +08:00
...headers,
},
body,
signal: abortController.signal, // 传递signal给fetchEventSource
2025-08-25 11:49:58 +08:00
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) {
2025-09-05 13:53:21 +08:00
// 请求失败时主动关闭SSE连接
abortController.abort();
2025-08-25 11:49:58 +08:00
handleError?.(error);
},
onclose() {
handleClose?.();
},
async onopen(response: Response) {
handleOpen?.(response);
},
});
// 返回abort方法供外部调用
return {
abort: () => abortController.abort(),
};
2025-08-25 11:49:58 +08:00
};