Vue 如何使用WebSocket与服务器建立链接 持续保持通信

2023-10-28

WebSocket

浏览器通过JavaScript向服务器发出建立WebSocket链接的请求,链接建立后,客户端和服务器端就可以通过TCP链接直接交互数据。WebSocket链接后可以通过send()方法来向服务器发送数据,并通过onnessage事件来接受服务器返回的数据。

创建WebSocket对象

let ws = new WebSocket(server);

WebSocket属性

属性 描述
ws.readyState WebSocket.CONNECTING: 0正在链接
WebSocket.OPEN: 1 链接成功,可以通信
WebSocket.CLOSING: 2 链接正在关闭
WebSocket.CLOSED: 3 链接已经关闭,或者打开链接失败
ws.bufferedAmount 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。
ws.onopen 连接建立时触发
ws.onmessage 客户端接收服务端数据时触发
ws.onerror 通信发生错误时触发
ws.onclose 连接关闭时触发
ws.binaryType 指定有链接所传递的二进制数据类型(可选值:blobarraybuffer)

WebSocket 方法

方法 描述
ws.send() 使用链接发送数据
ws.close() 关闭链接

WebSocket使用

创建WebSocket实例

首先判断当前浏览器是否支持WebSocket,如果支持则创建WebSocket实例,并初始化事件函数。

let ws = null;
const server = `ws://xxx.xx.xxx.xxx:xxxx`;// WebSocket服务地址
let createWebSocket = (server) => {
  try {
    if(window["WebSocket"]){
      ws = new WebSocket(server)
    }else if(window["MozWebSocket"]){
      ws = new MozWebSocket(server)
    } else  {
      Notification({message:"当前浏览器不支持websocket协议,建议使用Chrome浏览器",type:"success"})
    }
    initEventHandle()// 连接建立时触发
  } catch (e) {
    console.log("ERR-----------捕获异常", e)
  }
};

初始化事件函数

onerroronclose进行报错或链接断开后的一下业务逻辑操作(如:重连操作)
onopen:初始化状态(如:心跳检测、重连次数)
onmessage:对服务器发送的消息做处理

let initEventHandle = () => {
  // 连接报错
  ws.onerror = function (evt, e) {
    console.log("连接报错");
  };
  // 连接关闭
  ws.onclose = function (evt) {
    console.log("连接关闭---" + new Date().toLocaleTimeString());
  };
  // 链接成功
  ws.onopen = function (evt) {
    console.log("链接成功");
  };
  // 接受数据
  ws.onmessage = function (evt) {
     console.log("收到消息");
  };
};
重连机制

当浏览器断开WebSocket链接时或链接失败时,会出发oncloseonerror事件。我们可以在oncloseonerror中调用重连方法。为了避免重连方法的过多请求,可以定义一个状态来控制,也可以设置最大重连次数。

let count = 0;// 记录次数
let lockReconnect = false;// 避免ws重复连接
let reconnect = (server) => {
  if (count >= 5) return console.log("超出重连次数!");
  if (lockReconnect) return false;
  lockReconnect = true;
  setTimeout(function () {     // 设置延迟避免请求过多
    console.log("6----------开始重连");
    lockReconnect = false;
    count++;
  }, 5000);
};

在这里插入图片描述

心跳检测

为了保证WebSocket与服务器之间正常通信,可以每隔一段时间通过send()方法向服务器发送一个心跳信息。在onmessage拿到返回的心跳就说明连接正常。(服务器收到信息会返回相应的信息)

const heartCheck = {
  timeout: 25000,        // 设置心跳时间
  timeoutObj: null,
  serverTimeoutObj: null,
  reset: function () {
    clearTimeout(this.timeoutObj);
    clearTimeout(this.serverTimeoutObj);
    return this;
  },
  start: function () {
    const self = this;
    this.timeoutObj = setTimeout(function () {
      // 这里发送一个心跳,后端收到后,返回一个心跳消息,onmessage拿到返回的心跳就说明连接正常
      ws.send("ping----------Ping");
      self.serverTimeoutObj = setTimeout(function () {
        // 如果超过一定时间还没重置,说明后端主动断开了
        // 如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
        ws.close();
      },self.timeout)
    },this.timeout)
  }
};

监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。

window.onbeforeunload = function () {
  ws.close();
};

在Vue中使用WebSocket

main.js中引入全局并挂载到Vue原型上。

import socket from "@/utils/webSocket";
Vue.prototype.startWebSocket  = socket.startWebSocket;

完整代码:

// webSocket.js
import {Notification} from "element-ui";
import { getToken } from '@/utils/auth';

let count = 0;// 记录计数
let lockReconnect = false;//避免ws重复连接
const text1 = "您有新的订单,请及时处理!";
let ws = null;// 判断当前浏览器是否支持WebSocket
const server = `ws://xxx.xx.xxx.xxx:xxxx?Admin-Token=${getToken()}`;// WebSocket服务地址
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
  ws.close();
};
// 重连
let reconnect = (server) => {
  if (count >= 5) return console.log("超出重连次数!");
  if (lockReconnect) return false;
  lockReconnect = true;
  setTimeout(function () {     //没连接上会一直重连,设置延迟避免请求过多
    createWebSocket(server);
    lockReconnect = false;
    count++;
  }, 5000);
};
// 创建实例websocket
let createWebSocket = (server) => {
  try {
    if('WebSocket' in window){
      ws = new WebSocket(server)
    }else if('MozWebSocket' in window){
      ws = new MozWebSocket(server)
    } else  {
      Notification({message:"当前浏览器不支持websocket协议,建议使用现代浏览器",type:"success"})
    }
    // 连接建立时触发
    initEventHandle()
  } catch (e) {
    console.log("ERR-----------捕获异常", e)
  }
};
// 初始化事件函数
let initEventHandle = () => {
  // 连接报错
  ws.onerror = function (evt, e) {
    reconnect(server)
  };
  // 连接关闭
  ws.onclose = function (evt) {
    console.log("连接关闭---" + new Date().toLocaleTimeString());
    reconnect(server)
  };
  // 链接成功
  ws.onopen = function (evt) {
    heartCheck.reset().start();// 心跳检测重置
    count = 0;// 重置重连次数
  };
  // 接受数据
  ws.onmessage = function (evt) {// 如果获取到消息,心跳检测重置
    heartCheck.reset().start();// 拿到任何消息都说明当前连接是正常的
    let eventData  = undefined;
    try {
      eventData = JSON.parse(evt.data);
      handMsg(eventData)
    }catch (e) {
      console.log("捕获异常: 当前返回的数据不能解析;");
      console.log("内容:" + evt.data)
    }
  };
};
// 心跳检测
const heartCheck = {
  timeout: 25000,        // 设置心跳时间
  timeoutObj: null,
  serverTimeoutObj: null,
  reset: function () {
    clearTimeout(this.timeoutObj);
    clearTimeout(this.serverTimeoutObj);
    return this;
  },
  start: function () {
    const self = this;
    this.timeoutObj = setTimeout(function () {
      // 这里发送一个心跳,后端收到后,返回一个心跳消息,onmessage拿到返回的心跳就说明连接正常
      ws.send("ping--------------Ping");
      self.serverTimeoutObj = setTimeout(function () {
        // 如果超过一定时间还没重置,说明后端主动断开了
        // 如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
        ws.close();
      },self.timeout)
    },this.timeout)
  }
};
// 处理消息
let handMsg = (eventData) => {
  if (ws.readyState === WebSocket.OPEN) {
    if (eventData.code === "2000" && eventData.type === "order_notice") {
      Notification({message: text1,type:"warning"})
    }
  }
};
let startWebSocket = () => {
  createWebSocket(server)
};
export default { startWebSocket }

效果图:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue 如何使用WebSocket与服务器建立链接 持续保持通信 的相关文章

  • 暂停除了已激活的玩家之外的所有其他玩家。

    我有这个插件 它可以将不同的样式应用于 html5
  • ReferenceError:regeneratorRuntime未定义(但在范围内工作)

    我遇到过这种奇怪的情况 ReferenceError regeneratorRuntime is not defined 我已经设法在一个非常小的设置中重现 与同一问题上的类似问题相比 并且还注意到一些奇怪的行为 具体取决于是否使用范围 以
  • Chart.js 在初始化时设置活动段

    我正在使用 Chart js v2 并且尝试在加载图表时模拟圆环图上某个段的 悬停状态 因此看起来有一个部分已突出显示 我已经搜索和梳理了代码一天 但找不到一个好的方法来做到这一点 提前致谢 设置片段的悬停样式有点令人困惑 因为它没有真正记
  • 在 contenteditable div 中选择范围

    我有一个contenteditablediv 和其中的一些段落 这是我的代码 div style border solid 1px black width 300px height 300px div Hello world div div
  • 为什么我的淘汰单选按钮在另一个具有点击绑定的元素内时会失败?

    我有一个单选按钮列表 我想要点击 li 他们还检查单选按钮 这一切都有效 直到我放了一个name单选元素上的属性 然后我的代码停止工作 我的代码如下所示 ul li li ul li
  • 在新的 Google 协作平台 <嵌入 HTML> 中使用 localStorage 和 IndexedDB 不起作用

    我正在尝试将新的 Google 协作平台用于我开发的网页 但是 我在存储本地数据时遇到了问题 本地文件在 Windows 和 Apple safari chrome 中运行良好 从 Google 协作平台尝试一下 没有什么乐趣 此外 在 s
  • Chrome 中的性能问题

    我目前正在从事一个相对较大的项目 使用 AngularJs 构建 应用程序的一部分是一个表单 您可以向其中添加任意数量的页面 不幸的是 添加了很多不必要的垃圾 即表示表单模型的对象可能会变得非常大 在某些时候 Chrome 基本上无法处理它
  • 如何格式化 Highcharts 的 (x,y) 对数据的日期时间

    我的序列化方法会产生如下所示的日期时间字符串 2014 07 09T12 30 41Z 为什么下面的代码不起作用 function container highcharts xAxis type datetime series data x
  • 如何将内联 JavaScript 与 Express/Node.js 中动态生成的内容分开?

    对于具有几年 Web 开发经验但没有找到答案的人来说 这是一个有点菜鸟的问题程序员堆栈交换 or Google 我决定在这里问一下 我在用Express网络框架Node js 但这个问题并不特定于任何 Web 框架或编程语言 以下是从数据库
  • Snap.svg - 停止在可悬停元素的子元素上重新触发悬停事件

    对于一个项目 我使用的 SVG 形状由背景多边形和背景多边形上方的一些文本 我已将其转换为路径 组成 我正在使用 Snap svg 为我的形状设置动画 当我将鼠标悬停在多边形上时 形状应该缩放到特定尺寸 包括其中的所有内容 鼠标移开时 形状
  • 调整图像大小并将画布旋转 90 度

    这里有很多关于在 js 上使用画布旋转图像的主题 我阅读了其中的大部分内容 但无法找到解决我的问题的方法 我正在接收任何分辨率的图像 来自上传组件 我将其大小调整为 1024x768 如下所示 var canvas document cre
  • 尝试将数据存储在点击器网站中

    我正在尝试存储一个名为的变量score无论何时刷新 您都会一次又一次地使用它 我不明白的是它的代码是什么 我尝试了一些方法 但似乎都不起作用 这是我的答题器网站 但是当我尝试使用 JavaScript 来存储它时 它不起作用window o
  • 刷新页面时保存用户的选择

    我目前有一个页面显示不同团队的数据 我有一些数据 用户可以单击使其处于 打开 或 关闭 状态 并为每个数据显示不同的图标 它基本上就像一个清单 只是没有物理复选框 我想记住哪些 复选框 已被选中 即使在用户刷新页面或关闭浏览器并稍后返回之后
  • 为什么我们在打字稿中使用 HTMLInputElement ?

    我们为什么使用 document getElementById ipv as HTMLInputElement value 代替 document getElementById ipv value 功能getElementById返回具有类
  • 页面上使用 HTML Editor Extender 进行回发会导致 IE11 中出现 JavaScript 错误

    我已将 HTML 编辑器扩展程序添加到我正在处理的页面中 现在每当我在页面上发回帖子时 都会收到以下 Javascript 错误 JavaScript 运行时错误 参数无效 之后什么也没有发生 这在 IE10 或更低版本以及我所知道的所有其
  • Vuejs 2:去抖动不适用于手表选项

    当我在 VueJs 中反跳此函数时 如果我提供毫秒数作为原语 它就可以正常工作 但是 如果我将其提供为对 prop 的引用 它会忽略它 这是道具的缩写版本 props debounce type Number default 500 这是不
  • 在移动设备上滚动

    这个问题更多的是一个建议研究 我确实希望它对其他人有帮助 并且它不会关闭 因为我不太确定在哪里寻求有关此事的建议 在过去的 6 个月里 我一直在进行移动开发 我有机会处理各种设备上的各种情况和错误 最麻烦的是滚动问题 当涉及到在网站的多个区
  • 日期出现奇怪的错误,“未捕获非法访问”

    所以我试图找到最新的DateJavascript 可以处理 我把它减少到 9 月 275760 并增加了我开始捕获未捕获的天数illegal access例外new Date 09 24 275760 to new Date 10 13 2
  • 如何使用 crypto-js 解密 AES ECB

    我正在尝试将加密数据从 flash 客户端 发送到服务器端的 javascript 在 asp 中作为 jscript 运行 有几个 javascript Aes 库 但它们实际上没有文档记录 我正在尝试使用 crypto js 但无法让代
  • 在 CKEditor 中设置字体大小和字体系列

    我正在使用 ckeditor 我想问一下这个插件如何设置font family和font size 我尝试过使用 CKEDITOR config font defaultLabel Arial CKEDITOR config fontSiz

随机推荐

  • DC基础学习(六)Verilog语言结构到门级的映射2

    Design Compiler 以下简称DC 是Synopsys公司用于做电路综合的核心工具 可以将HDL描述的电路转换为基于工艺库的门级网表 本系列主要介绍综合相关的知识以及DC工具的使用 Verilog编码效率的高低是综合后电路性能高低
  • 微信网页开发:微信内h5使用wx-open-launch-weapp打开小程序,微信内h5使用wx-open-launch-app打开App的方案

    需求场景 当我们需要使用在微信客户端打开的h5页面 在页面上打开微信小程序或者唤起App时 我们需要使用微信js sdk提供的开放标签能力 这其中 使用wx open launch weapp标签打开微信小程序 使用wx open laun
  • 将“Encountered an improper argument“ 问题有效解决

    其错误提示为 Encountered an improper argument 错误原因 错误原因其实是因为我们在调试完结束时候 有断点 红色圆点 还没有去掉 所以我们一点击停止调试之后 keil就会马上弹出这个错误 然后你就会发现你的ke
  • 夏普ar2048s打印机驱动安装_驱动人生 下载安装打印机驱动的方法

    驱动人生 安装打印驱动的方法 支持USB 网络 注 电脑需要连接互联网 某些新款机型或可能不支持 不支持的型号请用自带驱动安装 或者到品牌官网下载驱动 注 下载 驱动人生 请到官网下载 请不要在第三方下载 第三方可能绑定有应用程序 安装时可
  • Sqlilabs-26

    来到了 Sqlilabs 大魔王的第 26 关关卡 来到页面就看到大大的 你的所有空格和过滤符都属于我们 这难得到机智的你吗 在此说下常见的绕过方法有 本来这应该在 25 关卡就说的 忘了 双写绕过 大小写绕过 编码绕过 如 hex URL
  • 通过这12张手绘图,搞懂什么是微服务架构

    点击上方 阿拉奇学Java 选择 置顶或者星标 优质文章第一时间送达 来源 juejin im post 5c0ba2bef265da614d08fefe 推荐阅读 SpringBoot中异步请求和异步调用 看这一篇就够了 下文 你将看到业
  • 【Linux成长史】Linux权限的详细讲解

    博客主页 博主链接 本文由 M malloc 原创 首发于 CSDN 学习专栏推荐 LeetCode刷题集 数据库专栏 初阶数据结构 欢迎点赞 收藏 留言 如有错误敬请指正 未来很长 值得我们全力奔赴更美好的生活 文章目录 本章详情 Lin
  • 算法效率分析基础-算法四

    主要内容 介绍研究算法效率的通用框架 介绍三种符号 O 读作O 读作omega 和 读作theta 这些数学借来的符号已经成为讨论算法效率的特定语言 使用通用框架系统对非递归算法进行分析 这种分析主要的工具是先定义一个代表算法运行时间的求和
  • QT信号槽的5种连接方式Qt::ConnectionType

    参考 QT信号槽的5种连接方式 非常溜 Qt QueuedConnection例子 666 Qt信号槽的五种连接方式 简洁清晰 Qt UniqueConnection 防止重复连接 综合 例子 updatethread h ifndef U
  • Python入门

    一 进制 1 什么是进制 进制就是进位的制度 一种进位的方式 2 常见的进制 二进制 0和1 0 1 十进制 0 9的整数 0 1 2 3 4 5 6 7 8 9 八进制 0 7的整数 用数字0开头 0 1 2 3 4 5 6 7 十六进制
  • ipconfig不是内部或外部命令

    错误背景 windows r 输入cmd dos命令输入ipconfig 出现不是内部或外部命令 解决方案 1 电脑 系统属性 环境变量 找到path 在末尾处 如没有分号就添加c windows system32 确定 windows r
  • Qt5 信号槽连接 函数重载、参数不一致问题

    Qt5中使用以下方式代替Qt4的信号槽连接 在编译时即对连接的函数指针进行检测 提高了安全性 而Qt4的连接方式是基于字符串的 只能在运行时进行检测 在Qt4的connect方法上右键 Refactor gt Convert connect
  • [数据库系统]第7讲 关系模式的优化知识点整理

    第1节 关系模型的好坏 ER模型转换的关系是否就是最优的关系 不一定 关系模型潜在的问题 添加异常 修改异常 删除异常 数据冗余 冗余 当数据的某些部分能由其他部分推导出来 就意味着存在冗余 冗余的存在是因为存在完整性约束 如何解决冗余问题
  • Transformer学习笔记

    The Illustrated Transformer Jay Alammar Visualizing machine learning one concept at a time jalammar github io 上面是图片出处 是否
  • CSS列表与表格

    目录 编辑 HTML 列表和 CSS 列表属性 不同的列表项目标记 实例 图像作为列表项标记 实例 定位列表项标记 实例 删除默认设置 实例 列表 简写属性 实例 设置列表的颜色样式 实例 更多实例 所有 CSS 列表属性 表格边框 实例
  • python PDF转docx库的安装与使用

    python PDF转docx库的安装与使用 下载 使用 三种方法 效果 下载 anaconda中直接通过anaconda prompt下载pdf2docx库 pip install pdf2docx 使用 三种方法 可以直接通过命令行使用
  • SpringMVC基础(5): SpringMVC常用注解

    目录 1 handler method 参数绑定常用注解 2 常用注解 1 PathVariable 2 RequestHeader CookieValue 3 Re Body 5 RequestBody和 RequestParam区别 6
  • 安装部署mysql、redis、minio、nginx

    离线安装部署mysql redis minio nginx jar包启动 系统环境 centos7 9 架构 X86 安装目录 server 记录安装笔记 依赖项在线安装的 下载离线依赖 yum install y nginx downlo
  • 最新升级的STM32CubeIDE属于一站式工具,本文带你体验它的强大

    目录 下载安装 配置生成代码 硬件在线调试 1 写在前面 2 STM32CubeIDE介绍 主要特点 3 STM32CubeIDE下载 4 STM32CubeMX安装 5创建工程并编译 下载安装 配置生成代码 硬件在线调试 1 写在前面 S
  • Vue 如何使用WebSocket与服务器建立链接 持续保持通信

    WebSocket 浏览器通过JavaScript向服务器发出建立WebSocket链接的请求 链接建立后 客户端和服务器端就可以通过TCP链接直接交互数据 WebSocket链接后可以通过send 方法来向服务器发送数据 并通过onnes