最佳websocket封装

封装了weboskect,完美支持了断网重连、自动心跳的功能,且完全兼容原生写法,无任何学习负担,开开箱即用!

import { EventDispatcher } from './dispatcher';export class WebSocketClient extends EventDispatcher {// #socket链接url = '';// #socket实例socket = null;// #重连次数reconnectAttempts = 0;// #最大重连数maxReconnectAttempts = 5;// #重连间隔reconnectInterval = 10000; // 10 seconds// #发送心跳数据间隔heartbeatInterval = 1000 * 30;// #计时器idheartbeatTimer = undefined;// #彻底终止wsstopWs = false;// *构造函数constructor(url) {super();this.url = url;}// >生命周期钩子onopen(callBack) {this.addEventListener('open', callBack);}onmessage(callBack) {this.addEventListener('message', callBack);}onclose(callBack) {this.addEventListener('close', callBack);}onerror(callBack) {this.addEventListener('error', callBack);}// >消息发送send(message) {if (this.socket && this.socket.readyState === WebSocket.OPEN) {this.socket.send(message);} else {console.error('[WebSocket] 未连接');}}// !初始化连接connect() {if (this.reconnectAttempts === 0) {this.log('WebSocket', `初始化连接中...          ${this.url}`);}if (this.socket && this.socket.readyState === WebSocket.OPEN) {return;}this.socket = new WebSocket(this.url);// !websocket连接成功this.socket.onopen = event => {this.stopWs = false;// 重置重连尝试成功连接this.reconnectAttempts = 0;// 在连接成功时停止当前的心跳检测并重新启动this.startHeartbeat();this.log('WebSocket', `连接成功,等待服务端数据推送[onopen]...     ${this.url}`);this.dispatchEvent('open', event);};this.socket.onmessage = event => {this.dispatchEvent('message', event);this.startHeartbeat();};this.socket.onclose = event => {if (this.reconnectAttempts === 0) {this.log('WebSocket', `连接断开[onclose]...    ${this.url}`);}if (!this.stopWs) {this.handleReconnect();}this.dispatchEvent('close', event);};this.socket.onerror = event => {if (this.reconnectAttempts === 0) {this.log('WebSocket', `连接异常[onerror]...    ${this.url}`);}this.closeHeartbeat();this.dispatchEvent('error', event);};}// > 断网重连逻辑handleReconnect() {if (this.reconnectAttempts < this.maxReconnectAttempts) {this.reconnectAttempts++;this.log('WebSocket', `尝试重连... (${this.reconnectAttempts}/${this.maxReconnectAttempts})       ${this.url}`);setTimeout(() => {this.connect();}, this.reconnectInterval);} else {this.closeHeartbeat();this.log('WebSocket', `最大重连失败,终止重连: ${this.url}`);}}// >关闭连接close() {if (this.socket) {this.stopWs = true;this.socket.close();this.socket = null;this.removeEventListener('open');this.removeEventListener('message');this.removeEventListener('close');this.removeEventListener('error');}this.closeHeartbeat();}// >开始心跳检测 -> 定时发送心跳消息startHeartbeat() {if (this.stopWs) return;if (this.heartbeatTimer) {this.closeHeartbeat();}this.heartbeatTimer = setInterval(() => {if (this.socket) {this.socket.send(JSON.stringify({ type: 'heartBeat', data: {} }));this.log('WebSocket', '送心跳数据...');} else {console.error('[WebSocket] 未连接');}}, this.heartbeatInterval);}// >关闭心跳closeHeartbeat() {clearInterval(this.heartbeatTimer);this.heartbeatTimer = undefined;}
}
class Log {static console = true;log(title, text) {if (!Log.console) return;if (import.meta.env.MODE === 'production') return;const color = '#ff4d4f';console.log(`%c ${title} %c ${text} %c`,`background:${color};border:1px solid ${color}; padding: 1px; border-radius: 2px 0 0 2px; color: #fff;`,`border:1px solid ${color}; padding: 1px; border-radius: 0 2px 2px 0; color: ${color};`,'background:transparent');}closeConsole() {Log.console = false;}
}
export class EventDispatcher extends Log {listeners = {};addEventListener(type, listener) {if (!this.listeners[type]) {this.listeners[type] = [];}if (this.listeners[type].indexOf(listener) === -1) {this.listeners[type].push(listener);}}removeEventListener(type) {this.listeners[type] = [];}dispatchEvent(type, data) {const listenerArray = this.listeners[type] || [];if (listenerArray.length === 0) return;listenerArray.forEach(listener => {listener.call(this, data);});}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/28763.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 TypeScript 写一个自己的 NPM 库

和JS写法差不多&#xff0c;就是要下一个TypeScript依赖 TypeScript编写共享库并发布到npm

linux MySQL基本操作

linux MySQL基本操作 文章目录 linux MySQL基本操作1. 操作语句启动 MySQL&#xff1a;查看 MySQL 运行状态&#xff1a;登录mysql 2. mysql 内语句密码永不过期设置远程访问刷新MySQL的系统权限相关表 1. 操作语句 启动 MySQL&#xff1a; systemctl start mysqldsystemctl …

早期发现,健康生活!第三届ZAODX世界肿瘤早筛大会圆满落幕!

2024年6月15日-16日&#xff0c;第三届ZAODX世界肿瘤早筛大会在雄安新区盛大开幕&#xff01;本次会议由河北雄安新区管理委员会公共服务局指导&#xff0c;第三届ZAODX世界肿瘤早筛大会组委会和早筛网主办&#xff0c;粤港澳大湾区精准医学研究院&#xff08;广州&#xff09;…

python GUI开发: tkinter事件处理的几种方式详解与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

GEM5 Garnet +DSENT: NoC power model 功耗模型

0. 简介 现在&#xff08;2024&#xff09;集成的是dsent。 Garnet作者&#xff0c;Turshar在2018年说Orion已经过时不在集成DSENT&#xff0c;但是集成DSENT的代码随着gem5更新也过时了&#xff0c;而他短期内没有更新的计划&#xff08;2018年说的&#xff09;。2023年还有一…

SpringBoot配置第三方专业缓存技术jetcache远程缓存方案和本地缓存方案

JetCache 是一个基于 Java 的分布式缓存解决方案&#xff0c;旨在提供高性能和可扩展性。它支持多种后端存储&#xff0c;如 Redis、Hazelcast、Tair 等&#xff0c;可以作为应用程序的缓存层&#xff0c;有效地提升数据访问性能和响应速度。 JetCache 的主要特点包括&#x…

springboot应用启动太慢排查 半天才打印日志

springboot应用启动太慢排查 半天才打印日志 解决办法 hostnamectl 命令查看主机名 vim /etc/hosts 加上主机名配置 127.0.0.1 hostname

Java_JDK下载与环境变量配置

目录 一、JDK下载安装 二、安装后配置环境变量 三、在编辑器里使用JDK 一、JDK下载安装 JDK 是Java开发工具包&#xff0c;它提供了用于开发和运行Java程序所需的工具和库。JDK包括Java编译器、Java虚拟机、Java标准库等。在IDEA中使用Java语言编写代码时&#xff0c;需要安…

为什么 Kubernetes 调试如此成问题?

在 Kubernetes 集群中调试应用程序问题通常感觉就像在迷宫中穿行。容器在设计上是短暂的&#xff0c;一旦部署就不可改变。当出现问题并且我们需要深入研究问题时&#xff0c;这会带来独特的挑战。在深入研究调试工具和技术之前&#xff0c;必须掌握核心问题&#xff1a;为什么…

openlayers 使用WMTS和XYZ加载天地图切片服务

openlayers 使用WMTS和XYZ加载天地图切片服务 本篇介绍一下使用openlayers加载天地图切片&#xff0c;两种方法&#xff1a; 使用WMTS使用XYZ 1 需求 openlayers加载天地图 2 分析 主要是不同类型source的使用 WMTS&#xff08;Web Map Tile Service&#xff09; 是 OGC…

一道全等三角形证明题

接着上次那道题 一道初中一年级几何题解析&#xff0c;再来做一道初中一年级下半学期几何题目&#xff1a; 傍晚丢垃圾散步时看到小小的学生学习群里丢了这个题目&#xff0c;想到一个解法。实在构造不出契合题干阅读材料结论的三角形&#xff0c;索性先根据这结论做一个推论…

ByteTrack

1. 论文中伪代码表示的流程图 2. 简要版 此图源自&#xff1a; ByteTrack多目标跟踪原理&#xff0c;白老师人工智能学堂 3. 详细版 根据ByteTrack-CPP-ncnn代码的数据流画的较为详细的流程图&#xff1a; 4. ByteTrack-CPP-ncnn的UML类图 Reference ByteTrack多目标跟踪原…

Excel小技巧| 批量多列多行转为一列

前期刘小生Star分享了Excel批量一列转多列多行&#xff0c;你学会了嘛&#xff01; 前期刘小生遇到需“对多列对行数据合并并找到唯一不重复的信息”&#xff0c;今天举一反三&#xff0c;继续沿用“替换等号”方法&#xff0c;将多列多行转为一列&#xff01; 下面一个模拟案…

xml与动态SQL

XML映射文件 规范 XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)。 ● XML映射文件的namespace属性为Mapper接口全限定名一致。 ● XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。 动态SQL &…

Excel批量一列转多列多行

你在公司或学校是否遇到过对人员进行分组&#xff0c;你是否曾一个一个复制粘贴&#xff0c;如只有100人&#xff0c;尚有时间一一分组&#xff0c;如1000人&#xff0c;甚至更多&#xff0c;不知分到“地老天荒”是否可以完成&#xff01; 今天刘小生分享一个方法“用替换等号…

环信beta版鸿蒙IM SDK发布!深度适配HarmonyOS NEXT系统

环信beta版鸿蒙IM SDK已正式发布&#xff01;欢迎有需求开发者体验集成&#xff01; 版本亮点 提供原生鸿蒙 SDK&#xff0c;支持原生 ArkTS 语言&#xff0c;全面拥抱鸿蒙生态提供鸿蒙系统上单聊、群聊、会话等能力和服务覆盖消息管理、用户属性、群租管理、离线推送.多设备…

【Echarts系列】平滑折线面积图

【Echarts系列】平滑折线面积图 序示例数据格式代码 序 为了节省后续开发学习成本&#xff0c;这个系列将记录我工作所用到的一些echarts图表。 示例 平滑折线面积图如图所示&#xff1a; 数据格式 data [{name: 2020年,value: 150},{name: 2021年,value: 168},{name: 2…

tmux 移植到ARM板端运行环境搭建

tmux源码下载&#xff1a; Home tmux/tmux Wiki GitHub 依赖的库代码下载&#xff1a; libevent&#xff1a; ncurses: 第一步&#xff1a;将以上三个代码解压放在同一个目录下&#xff0c;逐个编译 1. cd ./libevent-2.1.12-stable ./configure --host"arm-nextvp…

2024年粤港澳青少年信息学创新大赛图形化编程小低组真题试卷

2024年粤港澳青少年信息学创新大赛图形化编程小低组真题试卷 题目总数&#xff1a;16 总分数&#xff1a;100 单选题 第 1 题 单选题 默认小猫角色&#xff0c;以下哪个Scratch程序可以在点击绿旗后让小猫说”你好!"一共10秒? A. B. C. D. 第 2 题 单选题 …

50etf期权交易规则杠杆怎么计算?

今天带你了解50etf期权交易规则杠杆怎么计算&#xff1f;近年来&#xff0c;期权交易在股票市场中变得愈发流行&#xff0c;其中50ETF期权备受关注。作为一种金融衍生品&#xff0c;50ETF期权为投资者提供了更灵活的投资方式和更多的策略选择。 50etf期权交易规则杠杆怎么计算&…