Ts自封装WebSocket心跳重连
WebSocket是一种在单个TCP连接上进行全双工通信的协议,允许客户端和服务器之间进行双向实时通信。
所谓心跳机制,就是在长时间不使用WebSocket连接的情况下,通过服务器与客户端之间按照一定时间间隔进行少量数据的通信来达到确认连接稳定的手段。
Js提供的原生WebSocket的API较为简陋,博主这里对其进行简单封装,使其具有心跳机制。
一、搭建测试用本地服务器
博主使用node.js建立本地WebSocket服务器,代码如下
const WebSocket = require("ws");
const WebSocketServer = WebSocket.Server;
const wss = new WebSocketServer({ port: 3000 });
wss.on("connection", (ws) => {ws.on("message", (message, err) => {let data=JSON.parse(message.toString())console.log(data);if (err) {console.log(err);} else {if (data.type == "heartbeat") {ws.send(JSON.stringify({ "type": "heartbeat", "data": "---HeartBeatOK---" }));} else {ws.send(JSON.stringify({ "type": "normal","data": "Receive "+data.data+" OK" }));}}});
});
主要思路为,客户端建立连接后,进入wss.on('connection')的回调函数,开启message的监听。约定:消息为一个JSON字符串,其中包含type和data。
type是字符串类型,只有两个取值,一个是heartbeat,一个是normal。
type字段规定了消息体是心跳消息还是一般消息。
data是实际传输的数据。
这里数据传输遇到一点小问题,JSON字符串在传输过程中被转化为buffer格式,所以在接受message的时候需要调用toString方法转化为JSON字符串,然后才能用JSON.parse把内容解析出来。
如果心跳消息正常接受,服务器返回“---HeartBeatOK---”;如果一般消息正常接受,服务器返回“Receive ”(消息体)“ OK”。
二、进行WebSocket的封装
实现心跳的思路为,每隔一段时间(记为pingTimeOut),客户端发送数据到服务器,然后开始等待,如果等待时间超出规定时间(记为pongTimeOut),就启动重连函数,否则清空当前计时器。
值得注意的是,重连函数中应该设置重连的时间间隔,不然可能会因为多次连续重连报错。
首先建立一个参数协议
export interface OPTS {url: string;pingTimeOut?: number;pongTimeOut?: number;reconnectTimeOut?: number;
}
里面是我们可能需要修改的数值。其中url为必填,是WebSocket服务器的地址,reconnectTimeOut是连续重连的间隔时间。
export default class Websocket {private opts: OPTS;private ws: WebSocket;private lockReconnect: boolean = false;private forbidReconnect: boolean = false;private heartBeatTimer;private serverReplyTimer;constructor({url,pingTimeOut = 15000,pongTimeOut = 10000,reconnectTimeOut = 2000,}) {this.opts = {url: url,pingTimeOut: pingTimeOut,pongTimeOut: pongTimeOut,reconnectTimeOut: reconnectTimeOut,};this.createWebSocket();}
构造函数中传入我们需要的数值,非必填项设置默认值,将其赋给opts,然后调用createWebSocket方法。这个方法会在下文实现。首先,设置ws变量装载WebSocket示例对象,
设置lockReconnect,这个值用来控制:当重连程序运行中,不会再次触发重连程序。
forbidReconnect则是用来控制重连程序,当我们手动调用停止WebSocket连接的时候,禁止自动重连。
createWebSocket() {try {this.ws = new WebSocket(this.opts.url);this.EventHandler();} catch (e) {console.log("create",e);this.reconnect();}}
这里创建了一个WebSocket实例对象,传入opts参数中的url。
EventHandler() {this.ws.onerror = (e) => {console.log(e);this.reconnect();};this.ws.onmessage = (e) => {let result = JSON.parse(e.data).data;console.log(result);if (result == "---HeartBeatOK---") {clearTimeout(this.serverReplyTimer)}};this.ws.onopen = (e) => {this.startHeartBeat();};this.ws.onclose = (e) => {console.log(e);this.reconnect()};}
这里设置了所有当前监听ws状态变化的回调函数,其中,在onmessage回调函数中,如果收到服务器传来的心跳确认,就清除服务器回复计时器。之后的业务逻辑也可以在这里进行处理,或者另外封装业务处理函数,放在这里调用。
在onopen函数中开启心跳。
其余两种非正常状态,输出错误信息后启动重连程序。
心跳函数细节如下:
startHeartBeat() {if (this.heartBeatTimer) clearInterval(this.heartBeatTimer)console.log("start heart beat");this.ws.send(JSON.stringify({ type: "heartbeat", data: "-_-" }));this.heartBeatTimer = setInterval(() => {this.ws.send(JSON.stringify({ type: "heartbeat", data: "-_-" }));}, this.opts.pingTimeOut);}
如果创建过心跳计时器,但是由于重连的原因,重新开始心跳,就清除原来的计时器,重新创建一个心跳计时器。创建前需要立即发送一次心跳信号。计时器的时间间隔为opts中的参数。
reconnect() {clearInterval(this.heartBeatTimer)if (!this.lockReconnect && !this.forbidReconnect) {this.lockReconnect = true;setTimeout(() => {this.createWebSocket();this.lockReconnect = false;}, this.opts.reconnectTimeOut);}}
重连,清除心跳计时器,如果正在执行重连(lockReconnect控制),或者已经手动关闭连接,就直接退出。
经过规定时间(参数为连续重连的时间间隔)后重新创建WebSocket实例对象。
close() {this.ws.close();clearInterval(this.heartBeatTimer)this.forbidReconnect = true;}
手动关闭WebSocket连接的函数,设置禁用自动连接。同时清除心跳计时器。
博主使用Cocos进行测试,设置每次点击按钮传输0-9随机数字,同时每隔3秒进行一次心跳通信。
可以看到心跳通信正常,同时还可以进行数据传输。
相关文章:

Ts自封装WebSocket心跳重连
WebSocket是一种在单个TCP连接上进行全双工通信的协议,允许客户端和服务器之间进行双向实时通信。 所谓心跳机制,就是在长时间不使用WebSocket连接的情况下,通过服务器与客户端之间按照一定时间间隔进行少量数据的通信来达到确认连接稳定的手…...

【unity学习笔记】捏人+眨眼效果+口型效果
一、vriod捏人 1.在vroidstudio软件中捏人 2.导出模型(.vrm) 二、vrid导入unity的插件 1.在Git上搜索、打开univrm。 2.找到release页面找到合适的插件版本。(VRM-0.116.0_0f6c) 3.将univrm导入到工程中(assets)。 三…...
动态规划 | 最长公共子序列问题
文章目录 最长公共子序列题目描述问题分析程序代码复杂度分析 最短编辑距离题目描述问题分析程序代码复杂度分析 编辑距离题目描述输入格式输出格式 问题分析程序代码 最长公共子序列 题目描述 原题链接 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共…...

RuntimeError: The NVIDIA driver on your system is too old.
【报错】使用 AutoDL 复现实验时遇到 RuntimeError: The NVIDIA driver on your system is too old (found version 11070). Please update your GPU driver by downloading and installing a new version from the URL: http://www.nvidia.com/Download/index.aspx Alternativ…...

Java开发过程中的幂等性问题
幂等性问题: 1. 有时我们在填写某些 form表单 时,保存按钮不小心快速点了两次,表中竟然产生了两条重复的数据,只是id不一样。 2. 我们在项目中为了解决 接口超时 问题,通常会引入了 重试机制 。第一次请求接口超时了…...

基于Docker的软件环境部署脚本,持续更新~
使用时CtrlF搜索你想要的环境,如果没有你想要的环境,可以评论留言,会尽力补充。 本文提供的部署脚本默认参数仅适合开发测试,请根据实际情况调节参数。 数据库 MySQL version: 3.9 services:mysql:image: mysql:8.0.35container…...

C#上位机与欧姆龙PLC的通信08----开发自己的通讯库读写数据
1、介绍 前面已经完成了7项工作: C#上位机与欧姆龙PLC的通信01----项目背景-CSDN博客 C#上位机与欧姆龙PLC的通信02----搭建仿真环境-CSDN博客 C#上位机与欧姆龙PLC的通信03----创建项目工程-CSDN博客 C#上位机与欧姆龙PLC的通信04---- 欧姆龙plc的存储区 C#上…...

【Redis技术专区】「原理分析」探讨Redis6.0为何需要启用多线程
探讨Redis 6.0为何需要启用多线程 背景介绍开启多线程多线程的CPU核心配置IO多线程模式单线程处理方式多线程处理方式 为什么要开启多线程?充分利用多核CPU提高网络I/O效率响应现代应用需求 多线程实现启用多线程 最后总结 背景介绍 在Redis 6.0版本中,…...

simulink代码生成(六)——多级中断的配置
假如系统中存在多个中断,需要合理的配置中断的优先级与中断向量表;在代码生成中,要与中断向量表对应;中断相关的知识参照博客: DSP28335学习——中断向量表的初始化_中断向量表什么时候初始化-CSDN博客 F28335中断系…...

【Minikube Prometheus】基于Prometheus Grafana监控由Minikube创建的K8S集群
文章目录 1. 系统信息参数说明2. Docker安装3. minikube安装4. kubectl安装5. Helm安装6. 启动Kubernetes集群v1.28.37. 使用helm安装Prometheus8. 使用helm安装Grafana9. Grafana的Dashboard设定10. 设定Prometheus数据源11. 导入Kubernetes Dashboard12. 实验过程中的常见问题…...

无需翻墙|Stable Diffusion WebUI 安装|AI绘画
前言 最近终于有机会从围墙里往外看,了解到外面的世界已经有了天翻地覆的变化,感叹万千,笔者在本地mac,windows,linux,docker部署了不下20遍后,整理出来的linux极简避坑安装方案,供…...

在FC中手工创建虚拟机模板
1、Linux去除个性化信息 (1)编辑网卡配置文件,只保留以下内容(以RHEL 7为例) (2)清除主机密钥信息(开机会自动生成) (3)清除Machine IDÿ…...
OpenSSL provider
提供者 标准提供者默认提供者传统提供者FIPS 提供者基本提供者空提供者加载提供者 标准提供者 提供者是算法实现的容器。每当通过高级别 API 使用加密算法时,都会选择一个提供者。实际上是由该提供者实现执行所需的工作。OpenSSL 自带了五个提供者。在未来&#…...
pandas处理双周数据
处理文件题头格式 部门名称 年度名称 季节名称 商品名称 商品代码 品牌名称 品类名称 颜色名称 商店名称 0M 1L 1XL 27 28 29 2XL 30 31 32 33 3XL 4XL 5XL 6XL S 均1.导入包 导入源 pip install openpyxl -i https://pypi.doubanio.com/simple pip install pandas -i https…...

2023结婚成家,2024借势起飞
您好,我是码农飞哥(wei158556),感谢您阅读本文,欢迎一键三连哦。 💪🏻 1. Python基础专栏,基础知识一网打尽,9.9元买不了吃亏,买不了上当。 Python从入门到精…...
linux SHELL语句
shell编程 shell编程 一、初识shell 程序 语言 编程语言 自然语言 汉语 英语 计算机语言 c语言cjava php python go shell 编译型语言 c c java解释型语言 php python bash (不能闭源,开发难度低) 编译型语言:运行编译型语言是相对于解释型语言存在的ÿ…...

音频修复和增强软件:iZotope RX 10 (Win/Mac)中文汉化版
iZotope RX 是一款专业的音频修复和增强软件,一直是电影和电视节目中使用的行业标准音频修复工具,iZotope能够帮助用户对音频进行制作、后期合成处理、混音以及对损坏的音频进行修复,再解锁更多功能之后还能够对电影、游戏、电视之中的音频进…...
复试 || 就业day03(2023.12.29)算法篇
文章目录 前言同构字符串存在重复元素有效的字母异位词丢失的数字单词规律 前言 💫你好,我是辰chen,本文旨在准备考研复试或就业 💫文章题目大多来自于 leetcode,当然也可能来自洛谷或其他刷题平台 💫欢迎大…...

处理urllib.request.urlopen报错UnicodeEncodeError:‘ascii‘
参考:[Python3填坑之旅]一urllib模块网页爬虫访问中文网址出错 目录 一、报错内容 二、报错截图 三、解决方法 四、实例代码 五、运行截图 六、其他UnicodeEncodeError: ascii codec 问题 一、报错内容 UnicodeEncodeError: ascii codec cant encode charac…...

数据结构模拟实现LinkedList双向不循环链表
目录 一、双向不循环链表的概念 二、链表的接口 三、链表的方法实现 (1)display方法 (2)size方法 (3)contains方法 (4)addFirst方法 (5)addLast方法 …...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...