赞
踩
WebSocket 技术是一种在 Web 开发中常用的实时通信方式,它允许客户端和服务器之间建立持久性的双向连接,以便实时地传输数据。在 Vue.js 项目中,使用 WebSocket 可以轻松实现实时消息推送、即时通讯等功能。在这篇博客中,我们将介绍一个基于 Vue.js 的 WebSocket 模块的实现,并讨论其功能、作用以及应用方式。
废话不多说,先提供代码
// 在 store 中创建一个模块(WebSocket 模块) import {Notification} from 'element-ui'; import {getToken} from "@/utils/auth"; const state = { ws: null, heartCheckTimer: null, }; const mutations = { SET_WS(state, ws) { state.ws = ws; console.log("SET_WS", state.ws); }, CLEAR_WS(state) { state.ws = null; }, SET_HEART_CHECK_TIMER(state, timer) { state.heartCheckTimer = timer; }, }; const actions = { startWebSocket({commit, dispatch, state}) { if (getToken() && (!state.ws || state.ws.readyState !== WebSocket.OPEN)) { console.log("SOCKET_PATH:", process.env); const socketUrl = `${process.env.VUE_APP_SOCKET_PATH}/ws?token=${getToken()}`; const ws = new WebSocket(socketUrl); ws.onmessage = function (e) { console.log(`${new Date().toLocaleString()} >>>>> 收到消息 ${e.data}`, state.ws); if (e.data !== "pong") { Notification({ type: "info", title: '新消息', message: e.data, position: "top-right", duration: 3000, showClose: true }); } }; ws.onclose = function () { console.log(`${new Date().toLocaleString()} >>>>> 连接已关闭`); // 尝试重新连接 dispatch('reconnectWebSocket'); }; ws.onopen = function () { console.log(`${new Date().toLocaleString()} >>>>> 连接成功`, ws); Notification({ type: "success", title: '成功', message: '会话连接成功', position: "top-right", duration: 3000, showClose: true }); // 保存 WebSocket 连接信息 commit('SET_WS', ws); // // 在这里调用 sendWebSocketMessage,确保 state.ws 已经被正确设置 // 开始心跳检测 dispatch('startHeartCheck'); }; ws.onerror = function (e) { console.log(`${new Date().toLocaleString()} >>>>> 数据传输发生异常`, e); Notification({ type: "error", title: '错误', message: '会话连接异常,服务已断开', position: "top-right", duration: 3000, showClose: true }); }; } }, sendWebSocketMessage({state}, msg) { console.log(`${new Date().toLocaleString()} >>>>> 发送消息:${msg}`, state.ws); state.ws.send(msg); }, reconnectWebSocket({dispatch}) { dispatch('clearWebSocket'); // 递归调用,一直尝试重连 setTimeout(() => { dispatch('startWebSocket'); }, 6000); }, clearWebSocket({commit, state}) { if (state.ws) { state.ws.close(); commit('CLEAR_WS'); } }, startHeartCheck({commit, dispatch, state}) { console.log(`${new Date().toLocaleString()} >>>>> 开始心跳检测`, state.ws); // 清除之前的计时器 dispatch('clearHeartCheckTimer'); // 创建新的计时器 dispatch('sendWebSocketMessage', 'ping'); const timer = setInterval(() => { if (!state.ws || state.ws.readyState !== WebSocket.OPEN) { console.log(`${new Date().toLocaleString()} >>>>> 心跳检测失败,触发重连`, state.ws); dispatch('reconnectWebSocket'); } else { console.log(`${new Date().toLocaleString()} >>>>> 心跳正常,继续下一次心跳检测`, state.ws); dispatch('sendWebSocketMessage', 'ping'); } }, 1000 * 29); commit('SET_HEART_CHECK_TIMER', timer); }, clearHeartCheckTimer({commit, state}) { const timer = state.heartCheckTimer; timer && clearInterval(timer); commit('SET_HEART_CHECK_TIMER', null); }, }; export default { state, mutations, actions, };
该 WebSocket 模块提供了以下核心功能:
WebSocket 连接管理: 通过封装 WebSocket 的创建、连接、关闭等操作,实现了 WebSocket 连接的简便管理。
消息收发: 可以方便地发送和接收 WebSocket 消息,并在收到消息时进行相应的处理。
自动重连: 当 WebSocket 连接断开时,模块会自动尝试重新连接,确保持续的通信。
心跳检测: 集成了心跳检测机制,定期向服务器发送心跳消息,以确保连接的稳定性。
该模块的代码结构如下:
State: 维护了 WebSocket 连接对象(ws)和心跳检测定时器(heartCheckTimer)的状态。
Mutations: 提供了用于修改状态的同步方法,包括设置 WebSocket 对象、清除 WebSocket 对象以及设置心跳检测定时器。
Actions: 包含了异步的业务逻辑,如启动 WebSocket 连接、发送消息、重新连接、清除连接、启动心跳检测等。
首先,确保你的项目中已经安装了 element-ui,因为在收到新消息时,会使用 element-ui 的 Notification 组件进行通知。
npm install element-ui
在你的 Vuex store 中引入 WebSocket 模块:
// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import webSocketModule from './modules/webSocket';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
webSocket: webSocketModule,
// other modules...
},
// other configurations...
});
在需要使用 WebSocket 的地方,通过 Vuex 的 Action 启动 WebSocket 连接:
export default {
mounted() {
this.$store.dispatch('startWebSocket');
},
}
通过 Vuex Action 可以方便地发送消息,同时通过监听 WebSocket 模块的状态来处理接收到的消息:
// YourComponent.vue export default { methods: { sendMessage(message) { this.$store.dispatch('sendWebSocketMessage', message); }, }, computed: { websocket() { return this.$store.state.webSocket.ws; }, }, watch: { websocket(newVal) { if (newVal) { newVal.onmessage = (event) => { // 处理接收到的消息 console.log('Received message:', event.data); }; } }, }, }
通常,在页面刷新时,WebSocket 连接会被断开,因为整个应用重新加载。为了解决这个问题,你可以考虑以下方案:
监听页面刷新事件: 在页面即将刷新或关闭时,可以通过监听 beforeunload 事件来执行一些清理操作,例如关闭 WebSocket 连接。这样可以确保在页面刷新或关闭时,WebSocket 连接得到正常关闭。
mounted() { this.$nextTick(() => { // 初始化 WebSocket 连接 this.$store.dispatch('startWebSocket'); // 在这里保存 this.$store 到一个变量 const store = this.$store; // 在 beforeunload 事件中使用 store window.addEventListener('beforeunload', function (event) { store.dispatch('clearWebSocket'); // 在这里执行你的操作,例如保存数据 // const confirmationMessage = '确定要离开页面吗?'; // event.returnValue = confirmationMessage; // Standard for most browsers // return confirmationMessage; // For some older browsers }); }) }
代码放在App.vue下面的mouted即可
通过使用该 WebSocket 模块,我们可以轻松地在 Vue.js 项目中集成 WebSocket 功能,实现实时通信、消息推送等功能。模块的自动重连和心跳检测机制确保了连接的稳定性,而清晰的代码结构使得模块易于维护和扩展。在实际应用中,可以根据具体业务需求,结合 Vuex 状态管理和组件生命周期,灵活使用该模块,为项目提供更加强大的实时通信能力。
实际效果可查在线网站:https://web.yujky.cn
租户:体验租户
用户名:cxks
密码: cxks123
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。