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';
|
|
|
|
|
|
|
|
|
|
|
|
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<string, string | number>;
|
|
|
|
|
|
method?: string;
|
|
|
|
|
|
body?: any;
|
|
|
|
|
|
handleMessage?: (data: any) => void;
|
|
|
|
|
|
handleError?: (err: any) => number | null | undefined | void;
|
|
|
|
|
|
handleClose?: () => void;
|
|
|
|
|
|
handleOpen?: (response: Response) => Promise<void>;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 创建服务器发送事件(SSE)连接
|
|
|
|
|
|
* @param config SSE 配置
|
|
|
|
|
|
* @param url 可选的自定义 URL
|
|
|
|
|
|
*/
|
|
|
|
|
|
export default async (config: SSEConfig, url: string = DEFAULT_SSE_URL): Promise<void> => {
|
|
|
|
|
|
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) {
|
2025-08-25 18:01:04 +08:00
|
|
|
|
// console.error('SSE error:', error);
|
2025-08-25 11:49:58 +08:00
|
|
|
|
handleError?.(error);
|
|
|
|
|
|
},
|
|
|
|
|
|
onclose() {
|
2025-08-25 18:01:04 +08:00
|
|
|
|
// console.log('SSE connection closed');
|
2025-08-25 11:49:58 +08:00
|
|
|
|
handleClose?.();
|
|
|
|
|
|
},
|
|
|
|
|
|
async onopen(response: Response) {
|
|
|
|
|
|
// console.log('onopen', response);
|
|
|
|
|
|
handleOpen?.(response);
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|