WebSocket 在vue中的简单使用

WebSocket是一种在Web浏览器和Web服务器之间创建持久性连接的通信协议。它允许客户端和服务器之间进行全双工通信,这意味着服务器可以主动向客户端发送数据,而不需要客户端首先发起请求。通常用于实时数据传输的场景

在vue项目中使用 WebSocket,可以选择第三方库,也可以使用浏览器原生的 WebSocket API,这里仅介绍原生API的使用

------------------------------------------------------------------------------------------------------------------------------------------

简单的 demo

javaScript 复制代码
// YourComponent.vue
export default {
  data() {
    return {
      socket: null
    };
  },
  mounted() {
    // 初始化WebSocket连接
    this.socket = new WebSocket('ws://your-websocket-server-url');

    // 监听WebSocket事件
    this.socket.onopen = () => {
      console.log('WebSocket connected');
    };

    this.socket.onmessage = (event) => {
      console.log('Received message:', event.data);
      // 处理接收到的消息
    };

    // 其他事件监听和处理,如 this.socket.onclose, this.socket.onerror

    // 如果需要发送消息,可以调用 this.socket.send()
  },
  beforeDestroy() {
    // 在组件销毁前关闭WebSocket连接
    if (this.socket) {
      this.socket.close();
    }
  }
};
  • 上面 demo 使用new WebSocket('ws://your-websocket-server-url')来创建WebSocket实例,然后使用this.socket.onopenthis.socket.onmessage等事件处理函数来监听WebSocket的连接、接收消息等事件
  • 在组件销毁前,使用this.socket.close()来关闭WebSocket连接

封装一个 Socket 类

javaScript 复制代码
import EventBus from '@/eventBus';
class Socket {
    constructor() {
        // 基础URL
        this.baseUrl = `${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${window.location.host}`;
        // 最终的URL
        this.webSocketUrl = null;
        // webSocket实例
        this.ws = null;
        // 重连timeId
        this.reconnectTimer = 0;
        // 重连主动触发timeId
        this.emitReconnectTimer = 0;
        // 心跳timeId
        this.heartBeatTimer = 0;
        // 心跳失效关闭定时器
        this.receiverTimer = 0;
        // 暂存消息
        this.cacheMessage = [];
    }

    /**
     * 初始化
     * @param url websocket url
     */
    init(url) {
        if ('WebSocket' in window) {
            if (url) {
                this.webSocketUrl = `${this.baseUrl}${url}`;
            }
            this.ws = new WebSocket(this.webSocketUrl);
            this._bindListeners();
        } else {
            console.log('你的浏览器不支持WebSocket');
        }
    }

    /**
     * 手动关闭
     */
    close() {
        if (this.ws) {
            this.clearHeartBeat();
            this.ws.close();
        }
    }

    /**
     * 判断webSocket是否已连接
     * @returns {null|boolean}
     */
    ready() {
        return this.ws && this.ws.readyState === WebSocket.OPEN;
    }

    /**
     * 发送消息
     * @param message
     */
    sendMessage(message) {
        if (this.ready()) {
            this.ws.send(JSON.stringify(message));
        } else {
            this.cacheMessage.push(message);
        }
    }

    /**
     * 心跳机制
     */
    heartBeat() {
        this.clearHeartBeat();
        this.heartBeatTimer = setTimeout(() => {
            this.ws.send('ping');
            this.receiverTimer = setTimeout(() => {
                this.close();
            }, 20000);
        }, 20000);
    }

    /**
     * 清理心跳
     */
    clearHeartBeat() {
        if (this.heartBeatTimer) {
            clearTimeout(this.heartBeatTimer);
            this.heartBeatTimer = 0;
        }
        if (this.receiverTimer) {
            clearTimeout(this.receiverTimer);
            this.receiverTimer = 0;
        }
    }

    /**
     * 重连
     */
    reconnect() {
        this.destroyed();
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer);
            this.reconnectTimer = 0;
        }
        if (this.emitReconnectTimer) {
            clearTimeout(this.emitReconnectTimer);
            this.emitReconnectTimer = 0;
        }
        this.reconnectTimer = setTimeout(() => {
            this.init();
            // 重连后主动触发相应请求
            this.emitReconnectTimer = setTimeout(() => {
                EventBus.$emit('reconnect');
            }, 1000);
        }, 2000);
    }

    /**
     * 销毁webSocket
     */
    destroyed() {
        if (this.ws) {
            this.clearHeartBeat();
            this._unbindListeners();
            if (this.ready()) {
                this.ws.close();
            }
            this.ws = null;
        }
    }

    /**
     * 监听webSocket
     * @private
     */
    _bindListeners() {
        this.ws.onopen = e => {
            console.log('WebSocket onopen');
            this.heartBeat();
            if (this.cacheMessage && this.cacheMessage.length) {
                this.cacheMessage.forEach(message => {
                    this.sendMessage(message);
                });
                this.cacheMessage = [];
            }
        };
        this.ws.onmessage = e => {
            if (e.data === 'pong') {
                this.clearHeartBeat();
                this.heartBeat();
            } else {
                const data = JSON.parse(e.data);
                // 此处就可以对接受的数据进行处理
                // 可以通过
            }
        };
        this.ws.onclose = e => {
            console.log('WebSocket onclose', e);
            this.reconnect();
        };
        this.ws.onerror = e => {
            console.log('WebSocket onerror', e);
            this.reconnect();
        };
    }

    /**
     * 解除绑定
     * @private
     */
    _unbindListeners() {
        this.ws.onopen = null;
        this.ws.onmessage = null;
        this.ws.onclose = null;
        this.ws.onerror = null;
    }
}

export default new Socket();

在组件中使用

javaScript 复制代码
<script>
import Socket from '@/socket';
export default {
    name: 'index',
    created() {
        Socket.init('/api/dac/sembi/websocket/growthBoard/realtime');
    },
    destroyed() {
        Socket.destroyed();
    }
};
</script>
  • 组件中引入后,可以通过 Socket.sendMessage 发送信息
  • 组件接收信息的方就是用 EventBus,通过创建一个新的Vue实例并将其用作事件总线来实现EventBus的功能
javaScript 复制代码
import Vue from 'vue';

export default new Vue();
  • 然后在Socket接收信息后,通过 EventBus. <math xmlns="http://www.w3.org/1998/Math/MathML"> e m i t 触发一个事件,在组件里通过 E v e n t B u s . emit 触发一个事件,在组件里通过 EventBus. </math>emit触发一个事件,在组件里通过EventBus.on 监听一个事件,比如上面Socket重连时,通过EventBus.$emit('reconnect');告诉组件Socket重连了
相关推荐
等一场春雨7 小时前
springboot 3 websocket react 系统提示,选手实时数据更新监控
spring boot·websocket·react.js
却道天凉_好个秋7 小时前
音视频学习(二十八):websocket-flv
websocket·音视频·flv
龙哥·三年风水1 天前
workman服务端开发模式-应用开发-vue-element-admin封装websocket
分布式·websocket·vue
ZoeLandia2 天前
WebSocket | 背景 概念 原理 使用 优缺点及适用场景
网络·websocket·网络协议
zquwei2 天前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
carterslam2 天前
解决:websocket 1002 connection rejected 426upgrade required
网络·websocket·网络协议
抓住鼹鼠不撒手2 天前
xterm.js结合websocket实现web ssh
前端·javascript·websocket
学前端的小朱3 天前
Echarts实现大屏可视化
websocket·echarts·nodejs·vue3·vite·koa·cors
龙少95435 天前
【Http,Netty,Socket,WebSocket的应用场景和区别】
java·后端·websocket·网络协议·http
m0_748232925 天前
前端在WebSocket中加入Token
前端·websocket·网络协议