- A+
所属分类:Web前端
一个简单的 vue3 的 websocket hook. 有以下基础功能:
- 创建链接
- 失败重连
- 发送心跳包
import { ref } from "vue"; export interface WS_CONFIG { url: string; // ws链接地址 sendData?: Record<string, any>; // 请求数据 reconnectSec?: number; // 请求异常重连间隔 needHeart?: boolean; // 是否需要心跳 heartSec?: number; // 心跳间隔 heartData?: unknown; // 心跳时发送的数据 } export default function <T>({ url, sendData = {}, heartSec = 1000 * 30, needHeart = false, reconnectSec = 1000 * 30, heartData = "ping", }: WS_CONFIG) { // 响应数据 const wsData = ref<T | undefined>(); // 重试次数 const retryNumber = ref<number>(0); let socket: WebSocket | null = null; let heart_Interval: number | null = null; let lockConnect = false; let number = 0; // 创建链接 function connect() { // 重连之前,关闭上次的连接 if (socket) { socket.close(); } socket = new WebSocket(url); retryNumber.value = number++; // 连接成功回调 socket.onopen = () => { console.log(`${url} open event - ${new Date()}`); // 维持心跳 needHeart && heart(); // 清空重试次数 number = 0; retryNumber.value = 0; // 发送数据 socket?.send(JSON.stringify(sendData)); }; // 连接断开回调 socket.onclose = (e) => { console.log(` ${new Date()} ${url} close event code: ${e.code}; reason: ${e.reason}; isTrusted: ${e.isTrusted}; `); console.log(`reconnect - ${new Date()}`); // 进行重连 reconnect(); }; // 连接失败回调 socket.onerror = (e) => { console.log(`${url} error event`, e); // 进行重连 reconnect(); }; // 接收到数据 socket.onmessage = (e: MessageEvent<string>) => { const { data } = e; const _data = (typeof data === "string" ? JSON.parse(data) : data) as T; wsData.value = _data; }; } // 心跳函数,维持链接不断开 function heart() { clearHeart(); heart_Interval = setInterval(() => { socket?.send( typeof heartData === "string" ? heartData : JSON.stringify(heartData) ); }, heartSec); } // 断开心跳 function clearHeart() { heart_Interval && clearInterval(heart_Interval); } // 重连 function reconnect() { // 控制重连频率 if (lockConnect) { return; } lockConnect = true; // 清除心跳 clearHeart(); setTimeout(() => { lockConnect = false; connect(); }, reconnectSec); } connect(); // 关闭链接 function clearWS() { socket?.close(); clearHeart(); } return { wsData, retryNumber, clearWS, }; }