mirror of
https://gitee.com/JavaLionLi/plus-ui.git
synced 2026-09-16 00:38:19 +08:00
refactor(sse): 改用原生 EventSource + 事件总线,支持多 event name
- 新增 utils/sseEventBus.ts mitt 单例 - sse.ts 从 useEventSource 改为原生 EventSource,显式 addEventListener - 'message' event 沿用旧通知行为(noticeStore + ElNotification) - FORWARD_EVENTS(目前 customerservice)转发到事件总线供业务模块订阅
This commit is contained in:
parent
9a17d63de2
commit
0d03699fcf
@ -1,42 +1,67 @@
|
|||||||
import { getToken } from '@/utils/auth';
|
import { getToken } from '@/utils/auth';
|
||||||
import { ElNotification } from 'element-plus';
|
import { ElNotification } from 'element-plus';
|
||||||
import { useNoticeStore } from '@/store/modules/notice';
|
import { useNoticeStore } from '@/store/modules/notice';
|
||||||
|
import { getSseEventBus } from '@/utils/sseEventBus';
|
||||||
|
|
||||||
|
// Business-level SSE event names forwarded to the global event bus.
|
||||||
|
// Feature modules subscribe via getSseEventBus().on('xxx', handler).
|
||||||
|
const FORWARD_EVENTS = ['customerservice'];
|
||||||
|
|
||||||
|
const MAX_RETRIES = 5;
|
||||||
|
const RETRY_DELAY = 5000;
|
||||||
|
|
||||||
|
let eventSource: EventSource | null = null;
|
||||||
|
let retries = 0;
|
||||||
|
|
||||||
// 初始化
|
|
||||||
export const initSSE = (url: any) => {
|
export const initSSE = (url: any) => {
|
||||||
if (import.meta.env.VITE_APP_SSE === 'false') {
|
if (import.meta.env.VITE_APP_SSE === 'false') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
connect(url);
|
||||||
|
};
|
||||||
|
|
||||||
url = url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID;
|
function connect(url: string) {
|
||||||
const { data, error } = useEventSource(url, [], {
|
const fullUrl = url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID;
|
||||||
autoReconnect: {
|
eventSource = new EventSource(fullUrl);
|
||||||
retries: 5,
|
|
||||||
delay: 5000,
|
|
||||||
onFailed() {
|
|
||||||
console.log('Failed to connect after 5 retries');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(error, () => {
|
// Legacy "message" event: keep existing notification behavior
|
||||||
console.log('SSE connection error:', error.value);
|
eventSource.addEventListener('message', (e: MessageEvent) => {
|
||||||
error.value = null;
|
if (!e.data) return;
|
||||||
});
|
|
||||||
|
|
||||||
watch(data, () => {
|
|
||||||
if (!data.value) return;
|
|
||||||
useNoticeStore().addNotice({
|
useNoticeStore().addNotice({
|
||||||
message: data.value,
|
message: e.data,
|
||||||
read: false,
|
read: false,
|
||||||
time: new Date().toLocaleString()
|
time: new Date().toLocaleString()
|
||||||
});
|
});
|
||||||
ElNotification({
|
ElNotification({
|
||||||
title: '消息',
|
title: '消息',
|
||||||
message: data.value,
|
message: e.data,
|
||||||
type: 'success',
|
type: 'success',
|
||||||
duration: 3000
|
duration: 3000
|
||||||
});
|
});
|
||||||
data.value = null;
|
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
// Business events: forward to global bus, feature modules subscribe themselves
|
||||||
|
const bus = getSseEventBus();
|
||||||
|
FORWARD_EVENTS.forEach((name) => {
|
||||||
|
eventSource!.addEventListener(name, (e: MessageEvent) => {
|
||||||
|
bus.emit(name, e.data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
eventSource.onopen = () => {
|
||||||
|
retries = 0;
|
||||||
|
console.log('SSE connected');
|
||||||
|
};
|
||||||
|
|
||||||
|
eventSource.onerror = (err) => {
|
||||||
|
console.log('SSE connection error:', err);
|
||||||
|
eventSource?.close();
|
||||||
|
eventSource = null;
|
||||||
|
if (retries < MAX_RETRIES) {
|
||||||
|
retries += 1;
|
||||||
|
setTimeout(() => connect(url), RETRY_DELAY);
|
||||||
|
} else {
|
||||||
|
console.log('SSE failed after', MAX_RETRIES, 'retries');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
21
src/utils/sseEventBus.ts
Normal file
21
src/utils/sseEventBus.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import mitt, { Emitter } from 'mitt';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSE event bus events shape: protocol-level event name -> raw data string
|
||||||
|
* Consumers JSON.parse the payload themselves
|
||||||
|
*/
|
||||||
|
export type SseBusEvents = Record<string, string>;
|
||||||
|
|
||||||
|
let bus: Emitter<SseBusEvents> | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lazily-initialized singleton event bus
|
||||||
|
* Used by sse.ts to forward business event names (e.g. "customerservice")
|
||||||
|
* to feature modules without creating a second EventSource
|
||||||
|
*/
|
||||||
|
export function getSseEventBus(): Emitter<SseBusEvents> {
|
||||||
|
if (!bus) {
|
||||||
|
bus = mitt<SseBusEvents>();
|
||||||
|
}
|
||||||
|
return bus;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user