import { useCallback, useEffect, useState } from 'react'; import { wsClient } from './client'; import { WSMessage, WSMessageParams, MessageType } from './type'; interface UseWebSocketReturn { // 状态 messages: WSMessage[]; currentRoom: string | null; connecting: boolean; // 方法 joinRoom: (roomId: string) => Promise; leaveRoom: () => Promise; sendMessage: (messageParams: WSMessageParams) => Promise; // 工具方法 clearMessages: () => void; } export const useWebSocket = (): UseWebSocketReturn => { const [messages, setMessages] = useState([]); const [currentRoom, setCurrentRoom] = useState(null); const [connecting, setConnecting] = useState(false); // 消息处理器 const messageHandler = useCallback((message: WSMessage) => { setMessages((prev) => [...prev, message]); }, []); // 初始化 WebSocket 连接 useEffect(() => { const initConnection = async () => { try { setConnecting(true); await wsClient.connect(); const unsubscribe = wsClient.onMessage(messageHandler); return unsubscribe; } catch (error) { console.error('连接失败:', error); setMessages((prev) => [ ...prev, { action: 'error', data: { text: '连接失败,请刷新页面重试', type: MessageType.TEXT, }, }, ]); } finally { setConnecting(false); } }; const unsubscribePromise = initConnection(); return () => { unsubscribePromise.then((unsubscribe) => unsubscribe?.()); wsClient.disconnect(); }; }, [messageHandler]); // 加入房间 const joinRoom = async (roomId: string): Promise => { // 验证房间ID if (!roomId.trim()) { setMessages((prev) => [ ...prev, { action: 'error', data: { text: '请输入有效的房间ID', type: MessageType.TEXT, }, }, ]); return false; } // 检查是否正在连接 if (connecting) { return false; } try { setConnecting(true); await wsClient.joinRoom(roomId.trim()); setCurrentRoom(roomId.trim()); setMessages([]); // 清空消息历史 return true; } catch (error) { console.error('加入房间失败:', error); setMessages((prev) => [ ...prev, { action: 'error', data: { text: '加入房间失败,请重试', type: MessageType.TEXT, }, }, ]); return false; } finally { setConnecting(false); } }; // 离开房间 const leaveRoom = async (): Promise => { if (connecting) { return false; } try { await wsClient.disconnect(); setCurrentRoom(null); setMessages([]); // 清空消息历史 return true; } catch (error) { console.error('离开房间失败:', error); return false; } }; // 发送消息 const sendMessage = async (messageParams: WSMessageParams): Promise => { // 验证消息内容 if (!messageParams.text?.trim() && !messageParams.fileUri) { return false; } // 检查房间状态 if (!currentRoom) { setMessages((prev) => [ ...prev, { action: 'error', data: { text: '请先加入房间', type: MessageType.TEXT, }, }, ]); return false; } // 检查连接状态 if (connecting) { return false; } try { await wsClient.sendMessage(messageParams); return true; } catch (error) { console.error('发送消息失败:', error); setMessages((prev) => [ ...prev, { action: 'error', data: { text: '发送消息失败,请重试', type: MessageType.TEXT, }, }, ]); return false; } }; // 清空消息 const clearMessages = useCallback(() => { setMessages([]); }, []); return { // 状态 messages, currentRoom, connecting, // 方法 joinRoom, leaveRoom, sendMessage, // 工具方法 clearMessages, }; };