有效封装一个 WebSocket 供全局使用
前言
在现代 Web 应用中,实时通信已经成为越来越重要的一部分。而 WebSocket 技术的出现,使得实时通信变得更加高效和便捷。
WebSocket 协议是一种基于 TCP 协议的双向通信协议,它能够在客户端和服务器之间建立起持久性的连接,从而实现实时通信。
在前端开发中,为了更好地利用 WebSocket 技术,我们通常会对其进行封装,以便于全局调用并根据自己的业务做不同的预处理。
本文将介绍如何有效封装一个 WebSocket 供全局使用,并根据自己的业务做不同的预处理,实现更方便的调用,减少重复代码。
具体实现思想
我们将基于 Web API 提供的 WebSocket
类,封装一个 Socket
类,该类将提供以下功能:
-
建立 WebSocket 连接,并支持发送
query
参数。 -
发送、接收消息,支持对
WebSocket
的事件进行监听。 -
断开 WebSocket 连接。
-
支持心跳检测。
-
可以根据业务需要,对发送和接收的消息进行预处理。
接下来我们从实际使用的角度解释一下上面的代码,首先我们暴露了一个 useSocket
函数,该函数接收一个 options
配置项参数,支持的参数有:
-
url
:要连接的 WebSocket URL; -
protocols
:一个协议字符串或者一个包含协议字符串的数组; -
query
:可以通过 URL 传递给后端的查询参数; -
greet
:心跳检测的打招呼信息; -
customBase
:自定义的baseURL
,否则默认使用环境变量中定义的env.VITE_APP_BASE_WS
。
在调用该函数后,我们首先会判断当前用户的浏览器是否支持 WebSocket
,如果不支持给予用户提示。
然后我们实例化了一个 EventMap
类的实例对象 dep
,你可以把它当作是一个依赖收集桶,当用户订阅了某个 WebSocket
事件时,我们将收集这个事件对应的回调作为依赖,在事件触发时,再通知该依赖,然后调用该事件对应的回调函数。
接下来我们定义了一个初始的重连次数记录值 reconnectCount
为 0,每当这个 WebSocket
重连时,该值会自增。
之后我们实例化了自己封装的 Socket
类,并传入了我们上面的三个参数。 在 Socket
类的构造函数 constructor
中,我们先取出配置项,把 query
内的参数拼接在 URL 上,然后使用 super
调用父类的构造函数进行建立 WebSocket
连接。
之后我们缓存了当前 Socket
实例化时的参数,再调用 initSocket()
方法去进行 WebSocket
事件的监听:
-
onopen:触发 dep 内 open 对应的回调函数并且打开心跳检测;
-
onclose:触发 dep 内 close 对应的回调函数并且对关闭的 code 码进行判断,如果是非正常关闭连接,将会进行重连,如果重连次数达到阈值,则通知给用户;
-
onerror:触发 dep 内 error 对应的回调函数;
-
onmessage:接收到服务端返回的数据,可以先根据自身业务做一些预处理,比如我就根据不同的数据类型进行了数据解析的预处理,之后再触发 dep 内 message 对应的回调函数并传入处理过后的数据。
我们也暴露了一些成员方法以供实例对象使用:
-
subscribe:订阅 WebSocket 事件,传入事件类型并须是 EventTypes 内的类型之一,第二个参数则是回调函数;
-
sendMessage`:同样的,我们在给服务端发送数据之前也可以根据自身业务做一些预处理,比如我将需要转成 JSON 的数据,在这里统一转换后再发送给服务端;
-
closeSocket:关闭 WebSocket 连接;
-
heartCheckStart:开始心跳检测,会创建一个定时器,在一定时间之后(默认是 55s)给服务端发送信息确认连接是否正常;
-
clearHeartCheck:清除心跳检测定时器(如果当前 WebSocket 连接已经关闭,则自动清除);
-
resetHeartCheck:重置心跳检测定时器。
实践
为了封装一个 WebSocket 类供全局使用,我们可以创建一个 Socket
类,提供必要的方法和功能。以下是一个简化的示例代码,展示了如何实现这个类:
// websocket.js
class Socket {constructor(options) {this.url = options.url;this.protocols = options.protocols;this.query = options.query;this.greet = options.greet;this.reconnectCount = 0;this.initSocket();}initSocket() {this.socket = new WebSocket(this.url);this.socket.onopen = () => {console.log(this.greet);// ... 触发 open 事件的回调 ...};this.socket.onclose = (event) => {// ... 处理关闭事件 ...if (event.code !== 1000) {// 非正常关闭this.reconnect();}};this.socket.onerror = (error) => {// ... 处理错误事件 ...};this.socket.onmessage = (message) => {// ... 处理接收到的消息 ...};}reconnect() {this.reconnectCount++;// ... 实现重连逻辑 ...}sendMessage(data) {this.socket.send(JSON.stringify(data));}closeSocket() {this.socket.close();}heartCheckStart() {// ... 实现心跳检测 ...}clearHeartCheck() {// ... 清除心跳检测定时器 ...}resetHeartCheck() {// ... 重置心跳检测定时器 ...}
}// 导出 Socket 类
export default Socket;
说明
-
构造函数:接收配置选项并初始化 WebSocket 连接。
-
事件处理:处理
onopen
、onclose
、onerror
和onmessage
事件。 -
重连机制:在连接关闭时,如果不是正常关闭,则尝试重连。
-
消息发送:提供
sendMessage
方法以发送消息。 -
心跳检测:提供心跳检测相关的方法。
你可以根据具体需求进一步扩展和修改这个类。
相关文章:
有效封装一个 WebSocket 供全局使用
前言 在现代 Web 应用中,实时通信已经成为越来越重要的一部分。而 WebSocket 技术的出现,使得实时通信变得更加高效和便捷。 WebSocket 协议是一种基于 TCP 协议的双向通信协议,它能够在客户端和服务器之间建立起持久性的连接,从…...
使用expect工具实现远程批量修改服务器密码
使用expect工具实现远程批量修改服务器密码 linux服务器安装Expect工具 1、首先查看系统中是否有安装expect。 # whereis expect 2、Expect工具是依赖tcl的,需要先安装tcl #wget https://sourceforge.net/projects/tcl/files/Tcl/8.4.19/tcl8.4.19-src.tar.gz …...
算法日记39:洛谷P4170涂色(区间DP)
一、题目 二、题解: 1、题目解析: 1)刚刚开始阅读到题目,我们发现并没有什么思路,因此我们可以尝试来模拟一下样例的情况 2)通过观察我们发现 n 2 : n2: n2:可以拆分成 1 1 11 11来解决问题 n 3 : n3:…...
Python学习第十三天
正则表达式 什么是正则表达式:简单来说就是通过特殊符号匹配想要的字符串,正则表达式本身就是基于字符串的一套搜索规则,掌握了正则表达式对于字符串有了更深的把握和理解。 概念 官网概念:正则表达式(Regular Expres…...
python-53-分别使用flask和streamlit进行向量存储和检索的服务开发实战
文章目录 1 flask应用1.1 flask服务程序1.2 调用方式2 streamlit应用2.1 streamlit应用程序2.2 操作应用3 参考附录分别基于flask和streamlit,开发了向量存储和检索的应用程序,给出了主体框架的示例,可以在此基础上结合实际应用进行改写。 1 flask应用 1.1 flask服务程序 …...
Unity热更新方案HybridCLR+YooAsset,从零开始,保姆级教程,纯c#开发热更
文章目录: 一、前言二、创建空工程三、接入HybridCLR四、接入YooAsset五、搭建本地资源服务器Nginx六、实战七、最后八、后记 一、前言 unity热更有很多方案,各种lua热更,ILRuntime等,这里介绍的是YooAssetHybridCLR的热更方案&a…...
蓝桥杯嵌入式组第十二届省赛题目解析+STM32G431RBT6实现源码
文章目录 1.题目解析1.1 分而治之,藕断丝连1.2 模块化思维导图1.3 模块解析1.3.1 KEY模块1.3.2 LED模块1.3.3 LCD模块1.3.4 TIM模块1.3.5 UART模块1.3.5.1 uart数据解析 2.源码3.第十二届题目 前言:STM32G431RBT6实现嵌入式组第十二届题目解析源码&#…...
Pac-Man(吃豆人) 游戏
目录 前言 1. Pygame游戏开发基础 1.1 Pygame简介 1.2 游戏开发基本概念 1.3 Pygame核心模块介绍 2. 游戏设计与规划 2.1 游戏规则设计 2.2 游戏对象规划 2.3 技术方案选择 3. 创建游戏窗口与初始化 3.1 初始化Pygame环境 3.2 设置游戏窗口 3.3 定义颜色和游戏参数…...
Unity Dots从入门到精通 Mono和Dots通讯
文章目录 前言安装 DOTS 包Mono To DotsDots To Mono 前言 DOTS(面向数据的技术堆栈)是一套由 Unity 提供支持的技术,用于提供高性能游戏开发解决方案,特别适合需要处理大量数据的游戏,例如大型开放世界游戏。 本文讲…...
WLAN(无线局域网)安全
WLAN安全涉及到保护无线局域网免受各种威胁和攻击,以确保数据的保密性、完整性和可用性。以下是关于WLAN安全的多方面介绍: 一、主要安全威胁 窃听:攻击者利用特殊设备监听无线信号,获取传输中的数据,如用户的账号密…...
故障诊断——neo4j入门
文章目录 neo4jQuickStartDemo neo4j QuickStart 详情可见博客:https://www.cnblogs.com/nhdlb/p/18703804,使用docker拉取最近的一个版本进行创建 docker run -it -d -p 7474:7474 -p 7687:7687 \ -v /disk5/neo4j_docker/data:/data \ -v /disk5/ne…...
【商城实战(25)】解锁UniApp移动端适配秘籍,打造完美商城体验
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配…...
Qt 数据库操作(Sqlite)
数据库简介 关于数据库的基础知识这里就不做介绍了,相关博客可以查看: SQL基础知识 数据库学霸笔记 上面博客都写的比较详细,本文主要介绍如何使用Qt进行数据库相关操作,数据库分为关系型数据库和非关系型数据,关系…...
LINUX 指令大全
Linux服务器上有许多常用的命令,可以帮助你管理文件、目录、进程、网络和系统配置等。以下是一些常用的Linux命令: 文件和目录管理 ls:列出当前目录中的文件和子目录 bash lspwd:显示当前工作目录的路径 bash pwdcd:切…...
【Synchronized】不同的使用场景和案例
【Synchronized】不同的使用场景和案例 【一】锁的作用范围与锁对象【1】实例方法(对象锁)【2】静态方法(类锁)【3】代码块(显式指定锁对象)【4】类锁(通过Class对象显式锁定) 【二】…...
华为欧拉操作系统安装Docker服务
华为欧拉 20.03 操作系统安装 Docker 服务 一、安装前准备 系统环境检查 确认当前运行的操作系统为华为欧拉 24.03。可通过在终端执行以下命令查看: cat /etc/os - release欧拉系统可以使用以下命令: cat /etc/openEuler-release确保系统已连接互联…...
告别复杂日志解析 用bin2sql轻松实现MySQL数据闪回
mysqlbinlog⼯具使用 use test; CREATE TABLE t1 (id INT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(20) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;INSERT INTO t1(id, name) SELECT 101, tome101; INSERT INTO t1(id, name) SELECT 102, tome1…...
uniapp简单table表
<template><view class"container"><scroll-view scroll-x"true" scroll-y"true" class"table-scroll"><view class"table-header"><view class"table-cell fixed-column">序号<…...
prompt大师高效提示词解析
Prompt大师李继刚高效提示词示例解析 一、「汉语新解」提示词 核心结构 采用Lisp语言框架嵌套中文语义,通过(defun 新汉语老师 ()...)定义角色风格(融合奥斯卡王尔德、鲁迅的批判性语言),用(隐喻 (一针见血...))构建解释逻辑链。…...
uni-app如何发布项目为app_2025
参考大佬的:uni-app项目打包成apk(本地打包篇)_uniapp打包apk-CSDN博客 1、导入前配置 在 HBuilder X 中打开uni-app项目中的 mainifest.json 文件,appid没有的话可以点“重新获取” 2、打包 然后关注控制台,导出成功…...
MySQL与Canal、RabbitMQ集成指南
MySQL 部分 1. 查看是否开启 binlog MySQL 8 默认开启 binlog。可以通过以下命令查看是否开启: SHOW VARIABLES LIKE log_bin;如果返回结果为 ON,则表示 binlog 已开启。 Variable_nameValuelog_binON 2. 若未开启 binlog,则需手动配置 …...
新品发布|启英泰伦联合启明云端推出离在线语音大模型方案
当前,生成式大模型正以颠覆性姿态重塑人机交互的边界,并逐渐向终端场景渗透。然而,云端大模型在落地终端场景时面临两大挑战: 在真实噪声场景下容易听不清、误识别,影响交互准确性;云端处理冗余数据及大规…...
网编高级 day01
网编高级 day01 0. 大纲1. Modbus协议1.1. Modbus起源1.2. 分类1.3. Modbus TCP特点 2. Modbus TCP协议格式2.1. 报文头2.2. 寄存器2.3. 功能码 0. 大纲 协议: modbus协议:modbus TCP、modbus RTUhtml 网页:http协议Webserver 工具&#x…...
2001-2023年上市公司数字化转型年报词频统计(年报词频统计和MDA词频统计两种方式)(吴非、赵宸宇、甄红线300+关键词三种方法)
2001-2023年上市公司数字化转型年报词频统计(年报词频统计和MD&A词频统计两种方式)(吴非、赵宸宇、甄红线300关键词三种方法) 1、时间:2001-2023年 2、来源:上市公司年报 3、参考文献: …...
数据分析与AI丨AI Fabric:数据和人工智能架构的未来
AI Fabric 架构是模块化、可扩展且面向未来的,是现代商业环境中企业实现卓越的关键。 在当今商业环境中,数据分析和人工智能领域发展可谓日新月异。几乎每天都有新兴技术诞生,新的应用场景不断涌现,前沿探索持续拓展。可遗憾的是&…...
MQ消息发送不在MySQL事务中,该如何保证一致性?
在 MQ 消息发送与 MySQL 事务分离的场景下,可通过以下方案保障数据一致性: 一、核心原则 确保 业务操作成功 与 消息发送成功 的最终一致性,避免因网络抖动、服务宕机等异常导致以下问题: 场景1:业务操作成功但消息未…...
[rust] rust学习
rust学习 1. 项目组织结构 工程 # 创建一个工程 cargo new my-project工作空间 在 Rust 中,工作空间(Workspace) 是一个包含多个 Rust 项目的共享环境,用于管理多个 crate(库或可执行文件)。它允许多个…...
艾尔登复刻Ep1——客户端制作、场景切换、网络控制
需要添加的插件内容 Netcode for GameObjects:是一个为 Unity 游戏开发提供高级网络功能的 SDK。它的主要作用是允许开发者在其 GameObject 和 MonoBehaviour 工作流中集成网络功能,并且可以与多种底层传输层协议兼容。 具体内容请看:https:…...
正则表达式(复习)
文章目录 一、[]: 一个字符集合二、{}: 重复次数三、特殊符号四、(): 分组五、python代码示例六、注意 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个…...
密码学笔记
密码学 一、密码学基础概念 1. CIA三要素 机密性 (Confidentiality):信息不被未授权者访问。 例子:用钥匙锁住日记本,只有你有钥匙。 完整性 (Integrity):信息在传输/存储中不被篡改。 例子:快递包裹封条,…...
C#结构体(Struct)详解
在 C# 中,结构体(struct) 是一种值类型数据类型,适用于封装小型数据组。与类(class)不同,结构体在栈(Stack)上分配内存,且赋值时会发生值复制。以下是结构…...
Tomato靶机通关攻略
1.安装并开启靶机 2.用Kali查询靶机IP Kali 的IP 靶机的IP 3.访问靶机 4.用御剑扫描端口 5.获取敏感目录 分别访问三个目录 6.查看目录 发现info.php并进入 查看源码,发现文件包含漏洞 利用漏洞查看日志文件 http://192.168.40.139/antibot_image/antibots/info…...
Go Ebiten小游戏开发:俄罗斯方块
在这篇文章中,我们将一起开发一个简单的俄罗斯方块游戏,使用Go语言和Ebiten游戏库。Ebiten是一个轻量级的游戏库,适合快速开发2D游戏。我们将逐步构建游戏的基本功能,包括游戏逻辑、图形绘制和用户输入处理。 项目结构 我们的项…...
Github 2025-03-12 C开源项目日报Top5
根据Github Trendings的统计,今日(2025-03-12统计)共有5个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目5C++项目1Lean的LEDE源码:为国产龙芯LOONGSON SoC loongarch64/飞腾Phytium腾锐2000系列架构添加支持 创建周期:2338 天开发语言:C协议类…...
【机器学习-基础知识】统计和贝叶斯推断
1. 概率论基本概念回顾 1. 概率分布 定义: 概率分布(Probability Distribution)指的是随机变量所有可能取值及其对应概率的集合。它描述了一个随机变量可能取的所有值以及每个值被取到的概率。 对于离散型随机变量,使用概率质量函数来描述。对于连续型随机变量,使用概率…...
Unity3D 着色器优化(Shader Optimization)
前言 Unity3D 着色器(Shader)优化是提升渲染性能的关键环节,尤其是在移动设备或复杂场景中。以下是系统的优化策略和实践建议: 对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经…...
基于SpringBoot的“体育购物商城”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“体育购物商城”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体模块设计 前台用户登录界面 系统首页界面…...
数据库约束
数据库约束 1. NULL约束2. UNIQUE:唯一约束3. DEFAULT:默认值约束4. PRIMARY KEY:主键约束5. FOREIGN KEY:外键约束6. CHECK约束 数据库约束是关系型数据库的一个重要功能,主要作用是保证数据的正确性,也就…...
【经典算法】Leetcode-零钱兑换问题
一、题目 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。你可以认为每种硬币的数量是无限的…...
Go 语言使用Protobuf 进行序列化详解
文章目录 Go 语言使用Protobuf 进行序列化详解1. Protobuf是什么?2. 安装Protobuf 及 Go 依赖3. 编写.proto 文件4. 实现序列化和反序列化 Go 语言使用Protobuf 进行序列化详解 1. Protobuf是什么? 以下是 Protobuf 官方中文文档的概述: Protobuf(Protocol Buffers) 是一种…...
Windows控制台函数:标准输入输出流交互函数GetStdHandle()
目录 什么是 GetStdHandle? 它长什么样? 怎么用它? 它跟 std::cout 有什么不一样? GetStdHandle 是一个 Windows API 函数,用于获取标准输入、标准输出或标准错误设备的句柄。它定义在 Windows 的核心头文件 <…...
自然语言处理初学者指南
文章目录 一、说明二、自然语言处理发展史2.1 最早的自然语言处理简介2.2 历史2.3 NLP 的早期工作 三、NLP的现代方法3.1 单词编码3.2 循环神经网络3.3 强化学习3.4 深度学习 四、更进一步的方法 一、说明 对于初学者来说,自然语言处理的发展历史非常有必要了解&am…...
Kubernetes教程(七)了解集群、标签、Pod和Deployment
了解集群、标签、Pod和Deployment 一、K8s资源对象二、K8s集群1. Master2. Node 三、Namespace(命名空间)四、Label(标签)五、Pod1. 共享网络命名空间2. 共享数据 六、工作负载1. 设置副本数2. 应用升级 结语 Kubernetes的知识真的…...
【BUG分析】微服务无法读取Nacos中的共享配置
项目场景 基于Spring Cloud微服务的商城系统。 使用Nacos进行统一配置管理,在bootstrap.xml中读取配置参数。 问题描述 购物车微服务可以读取Nacos中的共享mybatis配置,商品管理微服务却读不到,启动报错提示无法配置数据库源: …...
SpringMVC (一)基础
目录 SpringMVC 一 简单使用 1 新建模块选择指定参数 2 创建实现类 3 将项目启动 4 运行结果:在浏览器当中响应执行 二 RequestMapping 三 请求限定 SpringMVC SpringMVC是Spring的web模块,用来开发Web应用,SpringMVC应用最终作为B/…...
【ES6】ES6中的类
基础定义和使用 class Animal {constructor(name, species, age) {this.name namethis.species speciesthis.age age} }let dog new Animal("Spot", "Dog", 4)私有变量 变量名前带#即可。 Getter 和Setter方法 继承 // 父类 class Point{construc…...
兴达易控Profinet 转 ModbusTCP跨网段通信模块
Profinet 转 ModbusTCP/跨网段通信模块 Profinet转ModbusTCP/跨网段通信模块,作为现代工业自动化系统中不可或缺的重要组件,正日益受到广泛关注和应用。 这种模块的核心功能是将Profinet网络协议转换为Modbus TCP协议,实现不同网络之间的无缝…...
linux 的免密切换用户PAM配置
/etc/pam.d/su是Linux系统中与用户切换(su命令)相关的PAM(Pluggable Authentication Modules,可插拔认证模块)配置文件。以下是对它的详细介绍: 简介 作用 PAM是一种用于管理系统认证的机制,…...
使用 Python pandas操作 Excel 文件
使用 Python pandas 操作 Excel 文件 flyfish pandas 是 Python 中一个强大的数据处理和分析库,它提供了丰富的数据结构(如 Series 和 DataFrame)和数据操作方法,能够方便地处理各种数据格式,包括 Excel 文件。 安装…...
UE5.5 Niagara 发射器粒子更新模块
Particle State (粒子状态)模块 Particle State 主要用于控制粒子的生存状态,包括死亡、消失、响应事件等。 Particle State Kill Particles When Lifetime Has Elapsed 当粒子的生命周期结束时,销毁这些粒子。 Lifetime &…...