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方法 …...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...