封装websocktHooks
import { ref, onMounted, onUnmounted } from 'vue';/*** webSocket的Hooks* @param {string} websocket链接地址* */
export function useWebSocket(url: string) {// 核心状态 const data: Ref<any> = ref(null);//收到websocket返回的数据const socket: Ref<WebSocket | null> = ref(null);//收到websocket返回的数据const isConnected: Ref<boolean> = ref(false);//是否链接成功const reconnectTimer: Ref<NodeJS.Timeout | null> = ref(null);//定时器变量const heartbeatTimer: Ref<NodeJS.Timeout | null> = ref(null);//定时器变量const HEARTBEAT_INTERVAL = 30000; // 心跳时间 const RECONNECT_DELAY = 5000;//重连时间/*** 创建连接* */ const connect = () => {if (socket.value) {socket.value.close();}// 初始化 WebSocket(传入 URL 和配置)socket.value = new WebSocket(url);// 连接成功 socket.value.onopen = () => {console.log('WebSocket 连接成功');isConnected.value = true;clearReconnectTimer();startHeartbeat();};// 接收消息 socket.value.onmessage = (event) => {try {data.value = JSON.parse(event.data);} catch (error) {console.error('消息解析失败', error);data.value = event.data;}};// 连接关闭 socket.value.onclose = (event) => {console.log(`WebSocket 关闭(代码:${event.code})`);isConnected.value = false;stopHeartbeat();startReconnectTimer();};// 连接错误socket.value.onerror = (error) => {console.error('WebSocket 错误', error);isConnected.value = false;};};/*** 发送消息* */const send = (message: any) => {if (isConnected.value && socket.value) {try {const sendData = typeof message === 'string' ? message : JSON.stringify(message);socket.value.send(sendData);} catch (error) {console.error('发送消息失败', error);}}};/*** 心跳检测* */const startHeartbeat = () => {stopHeartbeat();heartbeatTimer.value = setInterval(() => {if (isConnected.value && socket.value) {send({ type: 'heartbeat' });console.log('发送心跳包');}}, HEARTBEAT_INTERVAL);};/*** 停止心跳* */const stopHeartbeat = () => {if (heartbeatTimer.value) {clearInterval(heartbeatTimer.value);heartbeatTimer.value = null;}};/*** 启动重连计时器* */const startReconnectTimer = () => {clearReconnectTimer();reconnectTimer.value = setTimeout(() => {console.log('尝试重连...');connect();}, RECONNECT_DELAY);};/*** 清除重连计时器* */const clearReconnectTimer = () => {if (reconnectTimer.value) {clearTimeout(reconnectTimer.value);reconnectTimer.value = null;}};/*** 手动关闭连接* */const close = () => {if (socket.value) {socket.value.close(1000, '手动关闭');}stopHeartbeat();clearReconnectTimer();};// 组件挂载时连接onMounted(() => connect());// 组件卸载时彻底关闭onUnmounted(() => {close();});return {data,isConnected,send,connect,close};
}
使用
这样就可以请求到websocket了,并且每过30秒发送心跳,来判断连接是否正常,断开连接后5秒重新连接,关闭连接需要调用close()方法