- Remove MessageStateManager wrapper layer in favor of direct zustand store - Move service modules to services/ subdirectory (ConversationOperations, MessageDeduplication, MessageSendService, MessageSyncService, ReadReceiptManager, UserCacheService, WSMessageHandler) - Add new zustand-based store with subscriptionManager for event handling - Introduce React hooks for message state (useConversations, useMessages, useUnreadCount, etc.) - Update exports in index.ts to reflect new module structure - Deprecate messageManager.ts entry point in favor of message/index.ts - Maintain backward compatibility with existing MessageManager API
61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
/**
|
||
* 消息去重服务
|
||
* 处理消息去重逻辑,防止重复处理相同的消息
|
||
*/
|
||
|
||
import type { IMessageDeduplication } from '../types';
|
||
import {
|
||
PROCESSED_MESSAGE_ID_EXPIRY,
|
||
PROCESSED_MESSAGE_ID_MAX_SIZE,
|
||
} from '../constants';
|
||
|
||
export class MessageDeduplication implements IMessageDeduplication {
|
||
// 已处理消息ID集合(用于去重,防止ACK消息和正常消息重复处理)
|
||
private processedMessageIds: Set<string> = new Set();
|
||
private processedMessageIdsExpiry: Map<string, number> = new Map();
|
||
|
||
/**
|
||
* 检查消息是否已处理
|
||
*/
|
||
isMessageProcessed(messageId: string): boolean {
|
||
return this.processedMessageIds.has(messageId);
|
||
}
|
||
|
||
/**
|
||
* 标记消息已处理
|
||
*/
|
||
markMessageAsProcessed(messageId: string): void {
|
||
this.processedMessageIds.add(messageId);
|
||
this.processedMessageIdsExpiry.set(messageId, Date.now());
|
||
|
||
// 定期清理
|
||
if (this.processedMessageIds.size > PROCESSED_MESSAGE_ID_MAX_SIZE) {
|
||
this.cleanupProcessedMessageIds();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 清理过期的消息ID(防止内存泄漏)
|
||
*/
|
||
cleanupProcessedMessageIds(): void {
|
||
const now = Date.now();
|
||
for (const [id, timestamp] of this.processedMessageIdsExpiry.entries()) {
|
||
if (now - timestamp > PROCESSED_MESSAGE_ID_EXPIRY) {
|
||
this.processedMessageIds.delete(id);
|
||
this.processedMessageIdsExpiry.delete(id);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 重置所有已处理的消息ID
|
||
* 用于测试或需要清除缓存的场景
|
||
*/
|
||
reset(): void {
|
||
this.processedMessageIds.clear();
|
||
this.processedMessageIdsExpiry.clear();
|
||
}
|
||
}
|
||
|
||
// 单例导出
|
||
export const messageDeduplication = new MessageDeduplication(); |