* 获取或创建统一 socket 连接
()
| 23 | * 获取或创建统一 socket 连接 |
| 24 | */ |
| 25 | getSocket(): Socket { |
| 26 | if (!this.socket) { |
| 27 | this.socket = io(`${this.baseUrl}${NAMESPACE}`, { |
| 28 | autoConnect: false, |
| 29 | transports: ['websocket'], // 跳过 polling,直接用 WebSocket |
| 30 | reconnection: true, |
| 31 | reconnectionAttempts: Infinity, |
| 32 | reconnectionDelay: 1000, |
| 33 | reconnectionDelayMax: 10000, |
| 34 | }) |
| 35 | |
| 36 | // 连接事件日志 |
| 37 | this.socket.on('connect', () => { |
| 38 | console.log(`[Socket] Connected to ${NAMESPACE} t=${Date.now()}`) |
| 39 | }) |
| 40 | |
| 41 | this.socket.on('disconnect', (reason) => { |
| 42 | console.log(`[Socket] Disconnected from ${NAMESPACE}: t=${Date.now()}`, reason) |
| 43 | }) |
| 44 | |
| 45 | this.socket.on('connect_error', (error) => { |
| 46 | console.error(`[Socket] Connection error on ${NAMESPACE}: t=${Date.now()}`, error.message) |
| 47 | }) |
| 48 | |
| 49 | // 添加原始事件监听用于调试 |
| 50 | if (DEBUG_SOCKET) { |
| 51 | this.socket.onAny((event, ...args) => { |
| 52 | if (event === ServerEvents.SESSION_PATCH) { |
| 53 | const payload = args[0] as { sessionId: string; patch: unknown[] }; |
| 54 | console.log(`[Socket:raw] t=${Date.now()} event=${event} sessionId=${payload.sessionId} ops=${payload.patch?.length}`); |
| 55 | } else if (event === ServerEvents.SESSION_STDOUT) { |
| 56 | const payload = args[0] as { sessionId: string; data: string }; |
| 57 | console.log(`[Socket:raw] t=${Date.now()} event=${event} sessionId=${payload.sessionId} dataLen=${payload.data?.length}`); |
| 58 | } else { |
| 59 | console.log(`[Socket:raw] t=${Date.now()} event=${event}`); |
| 60 | } |
| 61 | }); |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | return this.socket |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * 连接到指定命名空间 |
no test coverage detected