在Vue3中使用Websocket可以让我们轻松地实现实时数据传输。为了方便使用,我们可以封装一个好用的Websocket类。
安装依赖
首先我们需要安装 ws
库来处理Websocket连接,使用以下命令进行安装:
npm install ws --save
使用ts+vue3封装组件
import { onUnmounted } from 'vue';//设置
interface SocketOptions {//心跳间隔heartbeatInterval?: number;//超时重传reconnectInterval?: number;//最大重传次数maxReconnectAttempts?: number;
}class Socket {//路径url: string;ws: WebSocket | null = null;opts: SocketOptions;//重传次数reconnectAttempts: number = 0;listeners: { [key: string]: Function[] } = {};//心跳间隔heartbeatInterval: number | null = null;//构造函数constructor(url: string, opts: SocketOptions = {}) {this.url = url;this.opts = {//心跳间隔heartbeatInterval: 30000,//超时重传reconnectInterval: 5000,//最大重传次数maxReconnectAttempts: 5,...opts};this.init();}//初始化init() {this.ws = new WebSocket(this.url);this.ws.onopen = this.onOpen.bind(this);this.ws.onmessage = this.onMessage.bind(this);this.ws.onerror = this.onError.bind(this);this.ws.onclose = this.onClose.bind(this);}//打开onOpen(event: Event) {console.log('WebSocket opened:', event);this.reconnectAttempts = 0;this.startHeartbeat();this.emit('open', event);}//收到的WebSocket消息onMessage(event: MessageEvent) {// console.log('WebSocket message received:', event.data);this.emit('message', event.data);}//错误onError(event: Event) {console.error('WebSocket error:', event);this.emit('error', event);}//重连逻辑中,在连接失败后自动重新连接onClose(event: CloseEvent) {console.log('WebSocket closed:', event);this.stopHeartbeat();this.emit('close', event);//重连逻辑中,在连接失败后自动重新连接,但会限制重连的次数和每次重连之间的间隔时间if (this.opts.maxReconnectAttempts !== 0 && this.reconnectAttempts < this.opts.maxReconnectAttempts!) {setTimeout(() => {// console.log("我有错误了1111111111111111111111111111111111111");this.reconnectAttempts++;this.init();}, this.opts.reconnectInterval);}}//开始心跳检测startHeartbeat() {if (!this.opts.heartbeatInterval) return;this.heartbeatInterval = window.setInterval(() => {if (this.ws?.readyState === WebSocket.OPEN) {this.ws.send('ping');}}, this.opts.heartbeatInterval);}//停止心跳检测stopHeartbeat() {if (this.heartbeatInterval) {clearInterval(this.heartbeatInterval);this.heartbeatInterval = null;}}//发送消息send(data: string) {if (this.ws?.readyState === WebSocket.OPEN) {this.ws.send(data);} else {console.error('WebSocket is not open. Cannot send:', data);}}//事件监听器注册功能的实现on(event: string, callback: Function) {if (!this.listeners[event]) {this.listeners[event] = [];}this.listeners[event].push(callback);}//从事件监听器中移除off(event: string) {if (this.listeners[event]) {delete this.listeners[event];}}//在事件监听器中触发一个指定的事件emit(event: string, data: any) {this.listeners[event]?.forEach(callback => callback(data));}
}export function useSocket(url: string, opts?: SocketOptions) {const socket = new Socket(url, opts);onUnmounted(() => {socket.off('open');socket.off('message');socket.off('error');socket.off('close');socket.ws?.close(); // 关闭WebSocket连接 });return {socket,send: socket.send.bind(socket),on: socket.on.bind(socket),off: socket.off.bind(socket)};
}
使用
import { useSocket } from "../../utils/websocket";const { socket, send, on, off } = useSocket(`ws://192.168.22.32:8000/v1/user/chats`
);on("close", () => console.log("Socket closed!"));//webSocket连接上服务器时on("open", event => {console.log("webSocket连接上服务器时", event);});
socket.on("message", data => {
console.log("Received data:", data); })send(xxxx);