- 使用缩略图替代原图展示,通过 sharp 库生成缓存缩略图 - 优化资产分组逻辑,避免不必要的重计算 - 添加 WebSocket 连接状态提示到输入框 - 使用 `useCallback` 和 `useRef` 优化组件渲染性能 - 添加 AbortController 支持请求取消,防止内存泄漏 - 添加 `disconnected` 事件处理,自动重置会话状态
61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
type MessageHandler = (data: Record<string, unknown>) => void;
|
|
|
|
class ChatSocket {
|
|
private ws: WebSocket | null = null;
|
|
private handlers: Map<string, MessageHandler[]> = new Map();
|
|
private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
|
|
private intentionallyClosed = false;
|
|
|
|
connect() {
|
|
this.intentionallyClosed = false;
|
|
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
const url = `${protocol}//${location.host}/ws`;
|
|
this.ws = new WebSocket(url);
|
|
this.ws.onopen = () => { this.emit('connected', {}); };
|
|
this.ws.onmessage = (event) => {
|
|
try { const { type, data } = JSON.parse(event.data); this.emit(type, data); } catch {}
|
|
};
|
|
this.ws.onclose = () => {
|
|
this.emit('disconnected', {});
|
|
if (!this.intentionallyClosed) {
|
|
this.reconnectTimer = setTimeout(() => this.connect(), 3000);
|
|
}
|
|
};
|
|
}
|
|
|
|
on(type: string, handler: MessageHandler) {
|
|
if (!this.handlers.has(type)) this.handlers.set(type, []);
|
|
this.handlers.get(type)!.push(handler);
|
|
}
|
|
|
|
off(type: string, handler: MessageHandler) {
|
|
const list = this.handlers.get(type);
|
|
if (list) {
|
|
const idx = list.indexOf(handler);
|
|
if (idx !== -1) list.splice(idx, 1);
|
|
}
|
|
}
|
|
|
|
send(type: string, data: Record<string, unknown> = {}) {
|
|
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
this.ws.send(JSON.stringify({ type, ...data }));
|
|
}
|
|
}
|
|
|
|
stop() { this.send('stop'); }
|
|
|
|
private emit(type: string, data: Record<string, unknown>) {
|
|
(this.handlers.get(type) || []).forEach((h) => h(data));
|
|
}
|
|
|
|
disconnect() {
|
|
this.intentionallyClosed = true;
|
|
if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
|
|
this.reconnectTimer = null;
|
|
this.ws?.close();
|
|
this.ws = null;
|
|
}
|
|
}
|
|
|
|
export const chatSocket = new ChatSocket();
|