首页 > 其他分享 >vue中websocket的使用---详解

vue中websocket的使用---详解

时间:2024-04-17 16:36:59浏览次数:15  
标签:vue WebSocket socket --- window websocket 连接 const

一、什么是webscoket

WebSockets 是一种先进的技术,它可以在用户的浏览器和服务器之间打开交互式通信会话。使用此 API,可以向服务器发送消息并接收事件驱动的响应,而无需通过轮询服务器的方式以获得响应。

 WebSockets 这种技术中有一个接口名为WebSocket,它是一个用于连接 WebSocket 服务器的主要接口,之后可以在这个连接上发送和接受数据。接下来的案例则是使用该接口创建一个WebSocket对象来进行管理。

二、创建对象

使用WebSocket接口创建对象,在创建对象之前,判断当前使用的浏览器是否支持该技术,不支持则无法进行一下步操作。

        使用WebSocket接口中的构造器创建对象,构造器中传入要连接的 URL,也就是WebSocket 服务器将响应的 URL。其中ws表示使用的是WebSocket协议;还有一种wss相较于ws更为安全,他们类似于http和https。

if ("WebSocket" in window) {
    const resRole = await getUserInfo();
    //这里对路径进行了配置,关于.env请看上一篇文章
    const wsUrl = process.env.VUE_APP_WEBSOCKET_API + `userCount/${resRole.user.userName}`;
    socket = new WebSocket(wsUrl);
    //上面两行等价于
    socket = new WebSocket("ws://localhost:8080/webSocketServer"); //直接写路径
    
  } else {
    Notification.error({
      title: "错误",
      message: "您的浏览器不支持websocket,请更换Chrome或者Firefox",
    });
  }

三、处理事件

 在上面对象创建成功的基础上,就可以使用该对象的处理事件了,主要分为以下四种:

事件 事件监听器 描述
open webSocket.onopen 用于指定链接成功后的回调函数
message webSocket.onmessage 用于指定当从服务器接受到信息时的回调函数
error webSocket.onerror 用于指定连接失败后的回调函数
close webSocket.onclose 用于指定链接关闭后的回调函数

四、webSocket基本已经了解,废话不多说直接上完整代码(我写了个js文件)

import { Notification } from "element-ui";
import { getToken } from "../utils/token";

var socket = null;//实例对象
var lockReconnect = false; //是否真正建立连接
var timeout = 20 * 1000; //20秒一次心跳
var timeoutObj = null; //心跳倒计时
var serverTimeoutObj = null; //服务心跳倒计时
var timeoutnum = null; //断开 重连倒计时

const initWebSocket = async () => {
  if ("WebSocket" in window) {
    const wsUrl = '链接地址';
    socket = new WebSocket(wsUrl);
    socket.onerror = webSocketOnError;
    socket.onmessage = webSocketOnMessage;
    socket.onclose = closeWebsocket;
    socket.onopen = openWebsocket;
  } else {
    Notification.error({
      title: "错误",
      message: "您的浏览器不支持websocket,请更换Chrome或者Firefox",
    });
  }
}

//建立连接
const openWebsocket = (e) => {
  start();
}

const start = ()=> {
  //开启心跳
  timeoutObj && clearTimeout(timeoutObj);
  serverTimeoutObj && clearTimeout(serverTimeoutObj);
  timeoutObj = setTimeout(function() {
    //这里发送一个心跳,后端收到后,返回一个心跳消息
    if (socket.readyState == 1) {
      //如果连接正常
      // socket.send("heartbeat");
    } else {
      //否则重连
      reconnect();
    }
    serverTimeoutObj = setTimeout(function() {
      //超时关闭
      socket.close();
    }, timeout);
  }, timeout);
}

//重新连接
const reconnect =() => { 
  if (lockReconnect) {
    return;
  }
  lockReconnect = true;
  //没连接上会一直重连,设置延迟避免请求过多
  timeoutnum && clearTimeout(timeoutnum);
  timeoutnum = setTimeout(function() {
    //新连接
    initWebSocket();
    lockReconnect = false;
  }, 1000);
}

//重置心跳
const reset =() => {
  //清除时间
  clearTimeout(timeoutObj);
  clearTimeout(serverTimeoutObj);
  //重启心跳
  start();
}

const sendWebsocket =(e) =>{
  // socket.send(`我发消息了`);
}

const webSocketOnError =(e) => {
  initWebSocket();
  reconnect();
  
}

//服务器返回的数据
const webSocketOnMessage=(e) => {
  //判断是否登录
  if (getToken()) {
    //window自定义事件[下面有说明]
    window.dispatchEvent(
      new CustomEvent("onmessageWS", {
        detail: {
          data: JSON.parse(e?.data),
        },
      })
    );
  }
  reset();
}

const closeWebsocket=(e) => {
  reconnect();
}

//断开连接
const close =() => {
//WebSocket对象也有发送和关闭的两个方法,只需要在自定义方法中分别调用send()和close()即可实现。
  socket.close();
}
//具体问题具体分析,把需要用到的方法暴露出去
export default { initWebSocket, sendWebsocket, webSocketOnMessage, close };

window自定义事件

//定义
window.dispatchEvent(new CustomEvent("事件名", {参数key:参数value}))
 
//监听
window.addEventListener("事件名", 参数key => {})

五、在main.js中挂载到vue原型上

import websocket from './utils/webSocket';
Vue.prototype.$websocket = websocket;

六、在需要建立连接的组件中这样写

  async mounted() {
    this.initWebSocket();
  },

  methods: {
    async initWebSocket() {
      this.$websocket.initWebSocket();
    },
  },

七、在需要从服务器获取的数据进行操作的组件中这样写

  mounted() {
    window.addEventListener("onmessageWS", this.getSocketData);
  },
  
  methods: {
    getSocketData(res) {
      this.PieValue = Number(res.detail.data.sendInfoStr.onlineUserCount);
      this.userNumValue = Number(res.detail.data.sendInfoStr.totalUserCount);
    },

八、在需要关闭连接的组件(比如退出时需要关闭)中这样写

//退出登录
    logOut() {
      this.$confirm("确定要退出登录吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.$message({
            type: "success",
            message: "退出成功!",
          });
          this.$websocket.close();
          localStorage.removeItem("token");
          this.$router.push("/login");
        }).catch(() => {
          this.$message({
            type: "info",
            message: "已取消退出",
          });
        });
    },

九、除了按钮可以主动关闭WebSocket连接以外,直接关闭浏览器窗口也会关闭连接,故此需要一个窗口监听器,来防止连接还没断开就关闭窗口,服务端出现异常。

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接
    window.onbeforeunload = function () {
        this.$websocket.close();
    }

 

标签:vue,WebSocket,socket,---,window,websocket,连接,const
From: https://www.cnblogs.com/liyunxi/p/18141071

相关文章

  • 前端项目安装node-sass依赖问题解决
    前端项目安装依赖node-sass问题解决记录:(项目中node版本14.16.0node-sass版本4.14.1)问题1:pnpnrunall:install后报错MSBUILD:errorMSB3428:解决方法:需要安装npminstall--globalwindows-build-tools1.1、npm全局安装windows-build-tools1.1安装过程中可能会出现......
  • WPF随笔收录-DataGrid固定右侧列
    一、前言在项目开发过程中,DataGrid是经常使用到的一个数据展示控件,而通常表格的最后一列是作为操作列存在,比如会有编辑、删除等功能按钮。但WPF的原始DataGrid中,默认只支持固定左侧列,这跟大家习惯性操作列放最后不符,今天就来介绍一种简单的方式实现固定右侧列。(这里的实现方式参......
  • uniCloud云函数概述---云对象
    云对象是普通云函数的升级版,功能和云函数是一样的。它在大多数场景下替代了普通云函数。云对象是对象化的云函数,比如一个文章云对象,它可以包括文章的创建,文章的删除,文章的编辑等功能。(一句话描述云对象:等同于PHP后端部份) 一、创建云对象打开项目,找到uniCloud/cloudfuncti......
  • 集英社-富硒土壤对茶叶品质影响 调查报告
    谨以此文,悼念我炸裂的计应数期中考试。下次不仅要带一个脑子做题,还得带一个脑子盯着它做题,不然第一个脑子容易跑偏刹不住车。得去黑市看一眼最近脑子市价如何,如果太贵还得卖点东西凑一凑。\[\newcommand{\d}{\mathrmd}\newcommand{\i}{\mathbfi}\]简介:你说的对,但是「集英社」......
  • Azkaban - [01] 概述
    简单的任务调度使用crontab、复杂的任务调度使用oozie、azkaban等开发调度系统。 一、为什么学习Azkaban  一个完整的数据分析系统通常都是由大量任务单元(shell脚本、java程序、MapReduce程序、Hive脚本等)组成。各任务单元之间存在先后及前后依赖关系,为了组织起这样的复杂......
  • SQL语法错误-java.sql.SQLSyntaxErrorException: You have an error in your SQL synt
    频繁爆出这样的错误:java.sql.SQLSyntaxErrorException:YouhaveanerrorinyourSQLsyntax;checkthemanualthatcorrespondstoyourMySQLserverversionfortherightsyntaxtousenear''atline1查阅了许多资料后,我怀疑报错可能与字段名不小心用了关键字有关......
  • conversion-operator
    参考文档user-definedconversionfunction-cppreference.comTheSafeBoolIdiom-知乎一般形式为operator*type*()const,比如:operatorint()const;operatorbool()const;operatorAA()const;自定义类型转换structTo{To()=default;To(conststru......
  • 点击菜单生成tabs(vue3.0)
    1.安装vuex npminstallvuex@next--save在main.js中引用vuex2.在main.js同级目录新建store/store.js文件 代码:import{createStore}from'vuex'exportdefaultcreateStore({ state:{ tabsList:[] }, mutations:{ addTab(state,tab){ //判断是否......
  • 5-02. 创建 AudioMixer 实现音乐音效的控制和切换
    创建AudioMixer修改AudioMixer可以增加Snapshots可以增加Groups创建一个只有背景音乐的快照静音的快照暴露音量选中Music,然后右键Music然后就能在ExposedParameters看到暴露出来的变量可以改名为MusicVolume用同样的方法暴露出Ambient并修改名字......
  • MBR40100PT-ASEMI肖特基二极管MBR40100PT
    编辑:llMBR40100PT-ASEMI肖特基二极管MBR40100PT型号:MBR40100PT品牌:ASEMI封装:TO-247最大平均正向电流(IF):40A最大循环峰值反向电压(VRRM):100V最大正向电压(VF):0.88V工作温度:-40°C~170°C反向恢复时间:5ns芯片个数:2芯片尺寸:130mil引脚数量:3正向浪涌电流(IFMS):400A包装方式:50/......