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重连了
相关推荐
911hzh13 分钟前
Flutter 音视频通话集成实战:WebSocket 做信令,WebRTC 传音视频,附详细事件时序图
websocket·flutter·音视频
TimeAground13 小时前
WebSocket 与长连接:从协议握手到断线重连的完整实战
websocket
2501_9216494916 小时前
企业定制金融数据 API:从架构设计到 Python 接入实战
大数据·开发语言·python·websocket·金融·量化
用户97436970725282 天前
5分钟搭建企业级实时消息推送系统
后端·websocket
Unbelievabletobe2 天前
港股api的WebSocket推送如何订阅多只股票
网络·websocket·网络协议
永远不会出bug2 天前
JAVA:WebSocket 「在线状态 + 强制挤下线通知」
网络·websocket·网络协议
net3m333 天前
所有esp_websocket_client_send。。。的地方都加锁,就不容易websocket 断线重连
网络·websocket·网络协议
琪露诺大湿4 天前
网页聊天系统——测试报告
java·软件测试·功能测试·websocket·html·项目·测试报告
iwS2o90XT4 天前
WebSocket编程:Java实现实时双向通信应用
java·websocket·网络协议
Rick19934 天前
SSE、WebSocket、HTTP
websocket·网络协议·http