Vue中使用websocket

场景描述

需要做一个功能:相同账号只允许登录一次,第二次再次登录提示“用户已登录!”。当前存在一个客户端、一个Web端共用一个后台。后台的处理逻辑是:监控websocket的状态,在onClose()方法中修改用户的登录状态。当前的web端并没有使用websocket,那么就没有办法退出或关闭浏览器重置用户状态。

实践

参考文章1:websocket基本用法
参考文章2:全局使用websocket(跨页面)

创建webSocketApi.js

// websocket 文件
export default {
    ws: {},
    setWs: function (newWs) {
        this.ws = newWs
    }
}

将websocket设置为全局变量

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './plugins/element.js'
import './assets/fonts/iconfont.css'
import websocket from './api/webSocketApi.js'
Vue.config.productionTip = false//关闭生产模式下给出的提示
// 将websocket设置为全局
Vue.prototype.websocket = websocket
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

登录页面创建websocket连接

注意:当前页面的that.ws赋值给了that.websocket.setWs(that.ws),所以当前页面中that.ws等价于that.websocket.ws

  //init函数可在页面加载的时候就进行初始化或者根据自己的业务需求在需要打开通讯的时候在进行初始化
    init() {
      let that = this;
      // 实例化socket,这里的实例化直接赋值给this.ws是为了后面可以在其它的函数中也能调用websocket方法,例如:this.ws.close(); 完成通信后关闭WebSocket连接
      if (process.env.NODE_ENV === "development") {
        //alert("开发环境");
        //this.ws = new WebSocket("ws://localhost:8080/ws/"+this.loginForm.userName)
        that.ws = new WebSocket("ws://localhost:8080/ws/"+this.loginForm.userName);
      }else {
        //alert("生产环境");
        //this.ws = new WebSocket("ws://localhost:8080/LPSAServer/ws/"+this.loginForm.userName)
        that.ws = new WebSocket("ws://localhost:8080/LPSAServer/ws/"+this.loginForm.userName);
      }
      that.websocket.setWs(that.ws)

      //监听是否连接成功
      that.ws.onopen = ()=> {
        console.log('ws连接状态:' +this.ws.readyState);
        //连接成功则发送一个数据
        that.ws.send('连接成功');
      }

      //接听服务器发回的信息并处理展示
      that.ws.onmessage = (data)=> {
        console.log('接收到来自服务器的消息:');
        console.log(data)
      }

      //监听连接关闭事件
      that.ws.onclose = ()=>{
        //监听整个过程中websocket的状态
        console.log('ws连接状态:' + this.ws.readyState);
      }

      // 主动关闭websocket连接
      //关闭
      /*   this.ws.onclose = function() {
           this.ws.close();
         };*/
      //监听并处理error事件
      that.ws.onerror = function(error) {
        console.log(error);
      }
    }

其它页面调用

比如:退出按钮,调用websocket的关闭方法

    // 退出登录
    logout() {
      this.delToken();
      this.$message.success('退出成功')
      this.$router.push("/login");
      //console.log(that.websocket.ws);
      // 关闭websocket连接
      let that = this;
      that.websocket.ws.close()
    },

发现问题:刷新会导致websocket连接关闭

解决方案:设置websocket断线重连机制
当主页面刷新的时候,重新建立websocket连接。
相关知识点:

  页面加载时只执行onload 
  页面关闭时先执行onbeforeunload,最后onunload 
  页面刷新时先执行onbeforeunload,然后onunload,最后onload  

HTML DOM addEventListener() 方法

websocketApi修改(适配全局)

// websocket 文件
export default {
    ws: {},
    setWs: function (userName) {
        //this.ws = newWs
        if (process.env.NODE_ENV === "development") {
            //alert("开发环境");
            //this.ws = new WebSocket("ws://localhost:8080/ws/"+this.loginForm.userName)
            this.ws = new WebSocket("ws://localhost:8080/ws/"+userName);
        }else {
            //alert("生产环境");
            //this.ws = new WebSocket("ws://localhost:8080/LPSAServer/ws/"+this.loginForm.userName)
            this.ws = new WebSocket("ws://localhost:8080/LPSAServer/ws/"+userName);
        }
    }
}

metheds中设置页面加载成功后的方法

 onloadFn(e) {
      //console.log('页面加载事件')
      // 页面刷新重连websocket
      let that = this
      //console.log(localStorage.getItem("name"))
      //console.log("页面被刷新了")
      that.websocket.setWs(localStorage.getItem("name"))
      //console.log(that.websocket.ws)
      console.log("websocket重连设置用户状态")
      updateUser(localStorage.getItem("name"))
    },

在create中注册事件

 window.addEventListener('load', e => this.onloadFn(e))
posted @   C紫枫  阅读(1516)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示