From 0d76d7a6deefd8c3e05188ee07d36ce75c968b51 Mon Sep 17 00:00:00 2001 From: Azure <983547216@qq.com> Date: Tue, 23 Jun 2026 11:10:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20WebSocket=20?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E7=AB=AF=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/websocket/roomSocket.ts | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/common/websocket/roomSocket.ts diff --git a/src/common/websocket/roomSocket.ts b/src/common/websocket/roomSocket.ts new file mode 100644 index 0000000..d1bba5b --- /dev/null +++ b/src/common/websocket/roomSocket.ts @@ -0,0 +1,77 @@ +import type { WsMessage } from '@/api/modules/game' + +/** WebSocket 连接回调 */ +export interface RoomSocketCallbacks { + onOpen?: () => void + onClose?: (event: CloseEvent) => void + onError?: (event: Event) => void + onMessage?: (message: WsMessage) => void +} + +/** WebSocket 客户端封装 */ +export interface RoomSocket { + /** 发送消息 */ + send: (type: string, data?: unknown) => void + /** 关闭连接 */ + close: () => void + /** 连接状态 */ + isOpen: () => boolean +} + +/** + * 创建房间 WebSocket 连接 + * + * @param roomId 房间 ID + * @param token 用户认证 token + * @param callbacks 事件回调 + * @returns RoomSocket 控制对象 + */ +export function createRoomSocket( + roomId: string, + token: string, + callbacks: RoomSocketCallbacks +): RoomSocket { + const wsUrl = `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}/ws/room?roomId=${encodeURIComponent(roomId)}&token=${encodeURIComponent(token)}` + + const ws = new WebSocket(wsUrl) + + ws.onopen = () => { + // eslint-disable-next-line no-console + console.log('[WS] 房间连接已建立, roomId=', roomId) + callbacks.onOpen?.() + } + + ws.onclose = (event) => { + // eslint-disable-next-line no-console + console.log('[WS] 房间连接已关闭, roomId=', roomId, 'code=', event.code) + callbacks.onClose?.(event) + } + + ws.onerror = (event) => { + console.error('[WS] 房间连接错误, roomId=', roomId, event) + callbacks.onError?.(event) + } + + ws.onmessage = (event) => { + try { + const message: WsMessage = JSON.parse(event.data as string) + callbacks.onMessage?.(message) + } catch (e) { + console.error('[WS] 消息解析失败:', e) + } + } + + return { + send(type: string, data?: unknown) { + if (ws.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify({ type, data })) + } + }, + close() { + ws.close(1000, '用户离开') + }, + isOpen() { + return ws.readyState === WebSocket.OPEN + } + } +}