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秒进行一次心跳通信。

可以看到心跳通信正常,同时还可以进行数据传输。

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

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

相关文章

IDC发布23Q3中国存储市场报告:浪潮信息逆势增长位居前二!

近日,权威调研机构IDC公布《中国企业级外部存储市场跟踪报告,2023Q3》。报告显示,2023年第三季度,中国企业级存储(ESS)市场规模达17.1亿美元,同比下降2.8%。其中,浪潮信息存销售额同比增长10.9%&#xff0c…

年终回顾与展望:CSDN成就之路,2023年AI浪潮展望及2024 Flag

文章目录 2023年在CSDN获得的肯定1,入围2023博客之星2,《有哪些让你目瞪口呆的Bug?》征文获得TOP33,通过创作者身份认证4,多篇文章被城市开发者社区收录5,多篇文章进入全站综合热榜6,积极参与社…

03.QT命名规范及快捷键(部分)

一、命名规范 1.类名 大驼峰规则:首字母大写,单词和单词之间首字母大写。 2.变量名 小驼峰规则:首字母小写,单词和单词之间首字母大写。 二、快捷键 1.代码操作相关 注释:ctrl / 运行:ctrl r 编译…

车载毫米波雷达及芯片新趋势研究3--自动驾驶、国产替代与外延场景需求快速增长打开市场空间

3.1 多传感器融合路线优势将不断扩大,引发更多毫米波雷达及芯片需求  纯视觉自动驾驶路线是通过以光学摄像头为传感器结合大量算法训练以模拟人类视觉驾驶为逻辑的自动驾驶方案。 纯视觉方案“轻硬件、重软件”,由其采用的摄像头成本较低,…

信号量机制(重要)-第二十八天

目录 前言 信号量机制 信号量S 整型信号量 记录型信号量 四个原语 实例(对于单核CPU的情况) 本节思维导图 前言 之前我们学习了关于进程互斥的四种软件实现方法(单标志法、双标志先检查法、双标志后检查法、Peterson算法)…

python 知识点

ping ping 不能带协议,如:ping baidu.com 引入包顺序 分三级,第一级是 Python 的内置库,第二级是第三方库,第三级是自己的代码。每一级用一个空行间隔 运算符 keyError:key不存在 列表推导式 创建字典 字…

python实现Ethernet/IP协议的客户端(二)

Ethernet/IP是一种工业自动化领域中常用的网络通信协议,它是基于标准以太网技术的应用层协议。作为工业领域的通信协议之一,Ethernet/IP 提供了一种在工业自动化设备之间实现通信和数据交换的标准化方法。python要实现Ethernet/IP的客户端,可…

【Java技术专题】「入门到精通系列」深入探索Java技术中常用到的六种加密技术和代码

深入探索Java技术中常用到的六种加密技术和实现 背景介绍柯克霍夫原则加密机制加密类型密码学原则 加密常用代表组件加密算法介绍Base64算法消息摘要算法(Message Digest)数据指纹MD5MD5算法的工作原理 SHASHA工作原理 对称加密DESDES的原理分析 3DES3DE…

Python+OpenGL绘制3D模型(六)材质文件载入和贴图映射

系列文章 一、逆向工程 Sketchup 逆向工程(一)破解.skp文件数据结构 Sketchup 逆向工程(二)分析三维模型数据结构 Sketchup 逆向工程(三)软件逆向工程从何处入手 Sketchup 逆向工程(四&#xf…

【openlayers-5】地图点、线、面等要素添加

1、添加点 //创建一个点 var point new ol.Feature({geometry: new ol.geom.Point([117.2, 35.8] ),}) //设置点的样式信息 point.setStyle(new ol.style.Style({//填充色fill: new ol.style.Fill({color: rgba(255, 255, 255, 0.2),}),//边线颜色stroke: new ol.style.Strok…

主成分分析(PCA):探索数据的核心

文章目录 前言1. 什么是 PCA ?2. PCA 的原理2.1 协方差和方差2.2 核心思想2.3 步骤 3. PCA 的应用场景4. PCA 的优缺点5. 示例:人脸识别5.1 完整代码5.2 运行结果 结语 前言 当今社会,数据无处不在。从社交媒体到金融交易,从医疗…

Valheim英灵神殿2456-2457-2458端口TCP和UDP开通

Valheim英灵神殿游戏需要开启云服务器2456、2457和2458三个端口,端口的TCP和UDP协议均要开通,云服务器吧yunfuwuqiba.com分享来详细说下Valheim英灵神殿游戏服务器端口说明: Valheim英灵神殿服务器端口 Valheim英灵神殿游戏要使用云服务器的…