yuang-framework-ui-common 1.0.104 → 1.0.105
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -66,10 +66,10 @@ export class FrameworkSseClient {
|
|
|
66
66
|
this.moduleCode = options?.moduleCode; // 初始化模块标识
|
|
67
67
|
this.onSseClientIdUpdate = options?.onSseClientIdUpdate; // 初始化回调
|
|
68
68
|
|
|
69
|
-
this.
|
|
69
|
+
this.connectSse();
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
private async
|
|
72
|
+
private async connectSse(): Promise<void> {
|
|
73
73
|
this.cleanup();
|
|
74
74
|
|
|
75
75
|
try {
|
|
@@ -115,13 +115,13 @@ export class FrameworkSseClient {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
if (!this.isManualClose) {
|
|
118
|
-
this.
|
|
118
|
+
this.handleReconnectSse();
|
|
119
119
|
}
|
|
120
120
|
} catch (error) {
|
|
121
121
|
console.error('[SSE] 连接/读取失败:', error);
|
|
122
122
|
this.errorHandler?.(error as Error);
|
|
123
123
|
if (!this.isManualClose) {
|
|
124
|
-
this.
|
|
124
|
+
this.handleReconnectSse();
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
}
|
|
@@ -170,6 +170,7 @@ export class FrameworkSseClient {
|
|
|
170
170
|
|
|
171
171
|
// 🔥 核心修复1:解析到 sseClientId 时即时处理
|
|
172
172
|
if (eventType === 'sseClientId') {
|
|
173
|
+
data = data.replace(/"/g,'');
|
|
173
174
|
console.log(`[SSE] [${this.moduleCode}] 获取到 sseClientId:`, data);
|
|
174
175
|
setLocalStorageItem(getSseClientIdKey(this.moduleCode), data, 60 * 30)
|
|
175
176
|
// 即时触发回调,同步到 Hook 的响应式变量
|
|
@@ -189,7 +190,7 @@ export class FrameworkSseClient {
|
|
|
189
190
|
this.messageHandler(data, mockEvent);
|
|
190
191
|
}
|
|
191
192
|
|
|
192
|
-
private
|
|
193
|
+
private handleReconnectSse(): void {
|
|
193
194
|
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
|
194
195
|
console.error(`[SSE] 已达到最大重连次数(${this.maxReconnectAttempts}),停止重连`);
|
|
195
196
|
this.errorHandler?.(new Error(`SSE 重连失败:已尝试 ${this.maxReconnectAttempts} 次`));
|
|
@@ -203,7 +204,7 @@ export class FrameworkSseClient {
|
|
|
203
204
|
this.reconnectAttempts++;
|
|
204
205
|
console.log(`[SSE] 准备第 ${this.reconnectAttempts} 次重连,间隔 ${this.reconnectInterval}ms`);
|
|
205
206
|
this.reconnectTimer = window.setTimeout(() => {
|
|
206
|
-
this.
|
|
207
|
+
this.connectSse();
|
|
207
208
|
this.reconnectTimer = null;
|
|
208
209
|
}, this.reconnectInterval);
|
|
209
210
|
}
|
|
@@ -225,13 +226,13 @@ export class FrameworkSseClient {
|
|
|
225
226
|
console.log(`[SSE] [${this.moduleCode}] 连接已手动关闭`);
|
|
226
227
|
}
|
|
227
228
|
|
|
228
|
-
|
|
229
|
+
reconnectSse(): void {
|
|
229
230
|
this.isManualClose = false;
|
|
230
|
-
this.
|
|
231
|
+
this.connectSse();
|
|
231
232
|
console.log(`[SSE] [${this.moduleCode}] 触发手动重连`);
|
|
232
233
|
}
|
|
233
234
|
|
|
234
|
-
|
|
235
|
+
isSseConnected(): boolean {
|
|
235
236
|
return !!this.streamReader && !this.isManualClose;
|
|
236
237
|
}
|
|
237
238
|
|
|
@@ -259,28 +260,28 @@ export interface SseMessage {
|
|
|
259
260
|
export interface UseSseResult {
|
|
260
261
|
sseClientId: Ref<string>;
|
|
261
262
|
sseMessageList: Ref<SseMessage[]>;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
263
|
+
isSseConnected: Ref<boolean>;
|
|
264
|
+
connectSse: (options?: FrameworkSseClientOptions) => void;
|
|
265
|
+
disconnectSse: () => void;
|
|
266
|
+
sendSseMessage: (message: string) => Promise<any>;
|
|
267
|
+
reconnectSse: () => void;
|
|
267
268
|
}
|
|
268
269
|
|
|
269
270
|
/**
|
|
270
271
|
* Vue3 + TS SSE 通用 Hook(修复 clientId 同步 + 模块隔离)
|
|
271
272
|
* @param sseUrl SSE 服务端连接地址
|
|
272
|
-
* @param
|
|
273
|
+
* @param sendSseMessageUrl 发送消息的接口地址
|
|
273
274
|
* @param moduleCode 模块标识(必填,用于隔离 clientId)
|
|
274
275
|
*/
|
|
275
276
|
export function useSse(
|
|
276
277
|
moduleCode: string = 'default'
|
|
277
278
|
): UseSseResult {
|
|
278
279
|
const sseUrl: string = '/framework-api/standard/framework-sse/connect';
|
|
279
|
-
const
|
|
280
|
+
const sendSseMessageUrl: string = '/framework-api/standard/framework-sse/sendMessage';
|
|
280
281
|
// 🔥 核心修复2:初始化时读取模块专属的 sseClientId
|
|
281
282
|
const sseClientId = ref<string>(getLocalStorageItem(getSseClientIdKey(moduleCode)) || '');
|
|
282
283
|
const sseMessageList = ref<SseMessage[]>([]);
|
|
283
|
-
const
|
|
284
|
+
const isSseConnected = ref<boolean>(false);
|
|
284
285
|
let sseClient: FrameworkSseClient | null = null;
|
|
285
286
|
|
|
286
287
|
// 消息处理回调(仅处理业务消息)
|
|
@@ -297,14 +298,14 @@ export function useSse(
|
|
|
297
298
|
|
|
298
299
|
// 连接成功回调
|
|
299
300
|
const openHandler: SseOpenHandler = () => {
|
|
300
|
-
|
|
301
|
+
isSseConnected.value = true;
|
|
301
302
|
ElMessage.success(`[${moduleCode}] SSE 连接成功`);
|
|
302
303
|
};
|
|
303
304
|
|
|
304
305
|
// 错误处理回调
|
|
305
306
|
const errorHandler: SseErrorHandler = (error) => {
|
|
306
307
|
console.error(`[SSE Hook] [${moduleCode}] 连接错误:`, error);
|
|
307
|
-
|
|
308
|
+
isSseConnected.value = false;
|
|
308
309
|
ElMessage.error(`[${moduleCode}] SSE 连接异常: ${(error as Error).message}`);
|
|
309
310
|
};
|
|
310
311
|
|
|
@@ -317,8 +318,8 @@ export function useSse(
|
|
|
317
318
|
/**
|
|
318
319
|
* 建立 SSE 连接(支持模块隔离 + 即时同步 clientId)
|
|
319
320
|
*/
|
|
320
|
-
const
|
|
321
|
-
if (sseClient?.
|
|
321
|
+
const connectSse = (options?: FrameworkSseClientOptions) => {
|
|
322
|
+
if (sseClient?.isSseConnected()) {
|
|
322
323
|
ElMessage.warning(`[${moduleCode}] 已存在有效的 SSE 连接,无需重复连接`);
|
|
323
324
|
return;
|
|
324
325
|
}
|
|
@@ -378,11 +379,11 @@ export function useSse(
|
|
|
378
379
|
/**
|
|
379
380
|
* 断开连接
|
|
380
381
|
*/
|
|
381
|
-
const
|
|
382
|
+
const disconnectSse = () => {
|
|
382
383
|
if (sseClient) {
|
|
383
384
|
sseClient.close();
|
|
384
385
|
sseClient = null;
|
|
385
|
-
|
|
386
|
+
isSseConnected.value = false;
|
|
386
387
|
ElMessage.info(`[${moduleCode}] SSE 连接已断开`);
|
|
387
388
|
}
|
|
388
389
|
};
|
|
@@ -390,9 +391,9 @@ export function useSse(
|
|
|
390
391
|
/**
|
|
391
392
|
* 手动重连
|
|
392
393
|
*/
|
|
393
|
-
const
|
|
394
|
+
const reconnectSse = () => {
|
|
394
395
|
if (sseClient) {
|
|
395
|
-
sseClient.
|
|
396
|
+
sseClient.reconnectSse();
|
|
396
397
|
ElMessage.info(`[${moduleCode}] 已触发 SSE 手动重连`);
|
|
397
398
|
} else {
|
|
398
399
|
ElMessage.warning(`[${moduleCode}] 暂无有效 SSE 连接,请先建立连接`);
|
|
@@ -402,7 +403,7 @@ export function useSse(
|
|
|
402
403
|
/**
|
|
403
404
|
* 发送消息(使用模块专属的 clientId)
|
|
404
405
|
*/
|
|
405
|
-
const
|
|
406
|
+
const sendSseMessage = async (sseMessage: string): Promise<any> => {
|
|
406
407
|
// 🔥 核心修复4:使用当前模块的 clientId(响应式变量)
|
|
407
408
|
if (!sseClientId.value) {
|
|
408
409
|
const errMsg = `[${moduleCode}] 未获取到 sseClientId,请先建立连接`;
|
|
@@ -411,7 +412,7 @@ export function useSse(
|
|
|
411
412
|
}
|
|
412
413
|
|
|
413
414
|
try {
|
|
414
|
-
const res = await http.post(
|
|
415
|
+
const res = await http.post(sendSseMessageUrl, {
|
|
415
416
|
sseClientId: sseClientId.value, // 使用最新的响应式 clientId
|
|
416
417
|
sseMessage
|
|
417
418
|
});
|
|
@@ -426,21 +427,21 @@ export function useSse(
|
|
|
426
427
|
|
|
427
428
|
// 组件卸载时清理
|
|
428
429
|
onUnmounted(() => {
|
|
429
|
-
|
|
430
|
+
disconnectSse();
|
|
430
431
|
});
|
|
431
432
|
|
|
432
433
|
// 页面关闭时清理
|
|
433
434
|
if (typeof window !== 'undefined') {
|
|
434
|
-
window.addEventListener('beforeunload',
|
|
435
|
+
window.addEventListener('beforeunload', disconnectSse);
|
|
435
436
|
}
|
|
436
437
|
|
|
437
438
|
return {
|
|
438
439
|
sseClientId,
|
|
439
440
|
sseMessageList,
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
441
|
+
isSseConnected,
|
|
442
|
+
connectSse,
|
|
443
|
+
disconnectSse,
|
|
444
|
+
sendSseMessage,
|
|
445
|
+
reconnectSse
|
|
445
446
|
};
|
|
446
447
|
}
|
package/package.json
CHANGED
|
@@ -7,22 +7,22 @@ http://localhost:8020/framework-ui-common/example/hooks/framework/framework-sse-
|
|
|
7
7
|
<div class="sse-btn-group">
|
|
8
8
|
<el-button
|
|
9
9
|
type="primary"
|
|
10
|
-
@click="
|
|
11
|
-
:disabled="
|
|
10
|
+
@click="connectSse()"
|
|
11
|
+
:disabled="isSseConnected"
|
|
12
12
|
:icon="Connection"
|
|
13
13
|
>
|
|
14
14
|
建立 SSE 连接
|
|
15
15
|
</el-button>
|
|
16
16
|
<el-button
|
|
17
|
-
@click="
|
|
18
|
-
:disabled="!
|
|
17
|
+
@click="disconnectSse()"
|
|
18
|
+
:disabled="!isSseConnected"
|
|
19
19
|
:icon="CircleClose"
|
|
20
20
|
>
|
|
21
21
|
断开连接
|
|
22
22
|
</el-button>
|
|
23
23
|
<el-button
|
|
24
|
-
@click="
|
|
25
|
-
:disabled="!
|
|
24
|
+
@click="reconnectSse()"
|
|
25
|
+
:disabled="!isSseConnected"
|
|
26
26
|
:icon="Refresh"
|
|
27
27
|
>
|
|
28
28
|
手动重连
|
|
@@ -78,11 +78,11 @@ import { useSse } from '../../../../../lib/hooks/framework/frameworkSseClient';
|
|
|
78
78
|
const {
|
|
79
79
|
sseClientId,
|
|
80
80
|
sseMessageList,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
isSseConnected,
|
|
82
|
+
connectSse,
|
|
83
|
+
disconnectSse,
|
|
84
|
+
sendSseMessage,
|
|
85
|
+
reconnectSse
|
|
86
86
|
} = useSse('example');
|
|
87
87
|
|
|
88
88
|
// 发送消息输入框绑定值
|
|
@@ -94,7 +94,7 @@ const handleSendMessage = () => {
|
|
|
94
94
|
ElMessage.warning('请输入消息内容');
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
sendSseMessage(inputMessage.value).then(() => {
|
|
98
98
|
// 发送成功后清空输入框
|
|
99
99
|
inputMessage.value = '';
|
|
100
100
|
}).catch(err => {
|