refactor(WebSocket): migrate from SSE to WebSocket for real-time messaging

- Replaced SSEClient with WSClient for handling real-time messaging.
- Updated ProcessMessageUseCase to initialize WebSocket listeners.
- Refactored messageService to prioritize WebSocket for sending messages, with fallback to HTTP.
- Removed sseService and adjusted imports across the application to utilize wsService.
- Enhanced message handling and connection management for improved performance and reliability.
This commit is contained in:
lafay
2026-03-26 22:04:46 +08:00
parent 4b89b50006
commit ba99900624
16 changed files with 986 additions and 659 deletions

View File

@@ -4,7 +4,7 @@
*/
import { messageStateManager, MessageStateManager } from './MessageStateManager';
import { sseMessageHandler, SSEMessageHandler } from './SSEMessageHandler';
import { wsMessageHandler, WSMessageHandler } from './WSMessageHandler';
import { messageSyncService, MessageSyncService } from './MessageSyncService';
import { readReceiptManager, ReadReceiptManager } from './ReadReceiptManager';
import { messageRepository } from '../../data/repositories/MessageRepository';
@@ -20,23 +20,23 @@ export type {
export class MessageManager {
private stateManager: MessageStateManager;
private sseHandler: SSEMessageHandler;
private wsHandler: WSMessageHandler;
private syncService: MessageSyncService;
private readManager: ReadReceiptManager;
private initialized: boolean = false;
private authUnsubscribe: (() => void) | null = null;
private sseUnsubscribe: (() => void) | null = null;
private wsUnsubscribe: (() => void) | null = null;
private currentUserId: string | null = null;
constructor() {
this.stateManager = messageStateManager;
this.sseHandler = sseMessageHandler;
this.wsHandler = wsMessageHandler;
this.syncService = messageSyncService;
this.readManager = readReceiptManager;
this.readManager.setStateManager(this.stateManager);
this.setupSSEHandlers();
this.setupWSHandlers();
this.initAuthListener();
}
@@ -58,8 +58,8 @@ export class MessageManager {
});
}
private setupSSEHandlers(): void {
this.sseUnsubscribe = this.sseHandler.subscribe((event) => {
private setupWSHandlers(): void {
this.wsUnsubscribe = this.wsHandler.subscribe((event) => {
switch (event.type) {
case 'chat_message':
case 'group_message':
@@ -89,7 +89,7 @@ export class MessageManager {
try {
console.log('[MessageManager] Initializing...');
this.sseHandler.connect();
this.wsHandler.connect();
const conversations = await this.syncService.syncConversations();
this.stateManager.setConversations(conversations);
@@ -224,14 +224,14 @@ export class MessageManager {
}
isConnected(): boolean {
return this.sseHandler.isConnected();
return this.wsHandler.isConnected();
}
reset(): void {
this.initialized = false;
this.stateManager.reset();
this.readManager.reset();
this.sseHandler.disconnect();
this.wsHandler.disconnect();
}
destroy(): void {
@@ -239,9 +239,9 @@ export class MessageManager {
this.authUnsubscribe();
this.authUnsubscribe = null;
}
if (this.sseUnsubscribe) {
this.sseUnsubscribe();
this.sseUnsubscribe = null;
if (this.wsUnsubscribe) {
this.wsUnsubscribe();
this.wsUnsubscribe = null;
}
this.reset();
}

View File

@@ -1,12 +1,12 @@
/**
* SSE
* SSE
* WS
* WS
*/
import { sseService, WSChatMessage, WSGroupChatMessage, WSReadMessage, WSGroupReadMessage, WSRecallMessage, WSGroupRecallMessage, WSGroupTypingMessage, WSGroupNoticeMessage, GroupNoticeType, WSMessage } from '../../services/sseService';
import { wsService, WSChatMessage, WSGroupChatMessage, WSReadMessage, WSGroupReadMessage, WSRecallMessage, WSGroupRecallMessage, WSGroupTypingMessage, WSGroupNoticeMessage, GroupNoticeType, WSMessage } from '../../services/wsService';
import type { Message, GroupNotice } from '../../core/entities/Message';
export type SSEEventType =
export type WSEventType =
| 'chat_message'
| 'group_message'
| 'read_receipt'
@@ -16,58 +16,58 @@ export type SSEEventType =
| 'typing'
| 'group_notice';
export interface SSEEvent {
type: SSEEventType;
export interface WSEvent {
type: WSEventType;
payload: any;
raw: any;
}
export type SSEEventHandler = (event: SSEEvent) => void;
export type WSEventHandler = (event: WSEvent) => void;
export class SSEMessageHandler {
export class WSMessageHandler {
private unsubscribeFns: Array<() => void> = [];
private handlers: Set<SSEEventHandler> = new Set();
private handlers: Set<WSEventHandler> = new Set();
connect(): void {
if (this.unsubscribeFns.length > 0) return;
// 监听私聊消息
const unsubChat = sseService.on('chat', (message) => {
const unsubChat = wsService.on('chat', (message) => {
this.emit('chat_message', this.parseChatMessage(message), message);
});
// 监听群聊消息
const unsubGroupMessage = sseService.on('group_message', (message) => {
const unsubGroupMessage = wsService.on('group_message', (message) => {
this.emit('group_message', this.parseGroupMessage(message), message);
});
// 监听私聊已读回执
const unsubRead = sseService.on('read', (message) => {
const unsubRead = wsService.on('read', (message) => {
this.emit('read_receipt', message, message);
});
// 监听群聊已读回执
const unsubGroupRead = sseService.on('group_read', (message) => {
const unsubGroupRead = wsService.on('group_read', (message) => {
this.emit('group_read_receipt', message, message);
});
// 监听私聊消息撤回
const unsubRecall = sseService.on('recall', (message) => {
const unsubRecall = wsService.on('recall', (message) => {
this.emit('message_recalled', message, message);
});
// 监听群聊消息撤回
const unsubGroupRecall = sseService.on('group_recall', (message) => {
const unsubGroupRecall = wsService.on('group_recall', (message) => {
this.emit('group_message_recalled', message, message);
});
// 监听群聊输入状态
const unsubGroupTyping = sseService.on('group_typing', (message) => {
const unsubGroupTyping = wsService.on('group_typing', (message) => {
this.emit('typing', message, message);
});
// 监听群通知
const unsubGroupNotice = sseService.on('group_notice', (message) => {
const unsubGroupNotice = wsService.on('group_notice', (message) => {
this.emit('group_notice', this.parseGroupNotice(message), message);
});
@@ -89,18 +89,18 @@ export class SSEMessageHandler {
this.handlers.clear();
}
subscribe(handler: SSEEventHandler): () => void {
subscribe(handler: WSEventHandler): () => void {
this.handlers.add(handler);
return () => this.handlers.delete(handler);
}
private emit(type: SSEEventType, payload: any, raw: any): void {
const event: SSEEvent = { type, payload, raw };
private emit(type: WSEventType, payload: any, raw: any): void {
const event: WSEvent = { type, payload, raw };
this.handlers.forEach(handler => {
try {
handler(event);
} catch (error) {
console.error('[SSEMessageHandler] Handler error:', error);
console.error('[WSMessageHandler] Handler error:', error);
}
});
}
@@ -141,8 +141,8 @@ export class SSEMessageHandler {
}
isConnected(): boolean {
return sseService.isConnected();
return wsService.isConnected();
}
}
export const sseMessageHandler = new SSEMessageHandler();
export const wsMessageHandler = new WSMessageHandler();

View File

@@ -12,8 +12,8 @@ export type { MessageState, MessageEvent, MessageSubscriber, MessageEventType }
// 导出同步服务
export { messageSyncService, MessageSyncService } from './MessageSyncService';
// 导出SSE处理器
export { sseMessageHandler, SSEMessageHandler } from './SSEMessageHandler';
// 导出WS处理器
export { wsMessageHandler, WSMessageHandler } from './WSMessageHandler';
// 导出已读管理器
export { readReceiptManager, ReadReceiptManager } from './ReadReceiptManager';