当前位置: 首页 > news >正文

【小程序websocket最佳实践,有心跳和断线重连】

小程序websocket最佳实践,有心跳和断线重连

封装了WebSocketHandler类,用于管理websocket链接,保证链接的稳定和可靠,该类主要适用于小程序,但其设计思想和方法也适用于其他平台。

export default class WebSocketHandler {constructor() {// 获取环境变量this.env = wx.getStorageSync('env');// 生产环境的 WebSocket 地址this.prod = 'www.xx.com';// 开发环境的 WebSocket 地址this.dev = 'www.xx.com';// 根据环境变量选择 WebSocket 地址this.path = `${(this.env == 'pro' || !this.env) ? this.prod : this.dev}`;// 构建 WebSocket URLthis.url = `wss://${this.path}/websocket`;// 重连次数限制this.limit = 0;// WebSocket 连接状态标志this.isClose = true;// 存储未发送的消息this.preParams = '';// 重连锁this.lockReconnect = false;// 重连定时器this.timer = null;// 心跳检测机制this.heartCheck = {timeout: 3000, // 心跳检测间隔timeoutObj: null, // 客户端定时器serverTimeoutObj: null, // 服务端定时器reset: function () {// 重置定时器clearTimeout(this.timeoutObj);clearTimeout(this.serverTimeoutObj);return this;},start: () => {// 启动心跳检测this.heartCheck.timeoutObj = setTimeout(() => {// 发送 PING 消息wx.sendSocketMessage({data: "PING",success() {// 发送成功}});// 设置服务端定时器,如果超时则关闭连接this.heartCheck.serverTimeoutObj = setTimeout(() => {wx.closeSocket();}, this.heartCheck.timeout);}, this.heartCheck.timeout);}};// 绑定 WebSocket 事件处理函数this._onSocketOpen();this._onSocketMessage();this._onSocketError();this._onSocketClose();}/*** 创建 WebSocket 连接* @param {Object} options - 建立连接时需要的配置信息* @param {string} options.userId - 用户 ID* @param {string} options.agentId - 代理 ID*/connect({ userId}) {if (!this.isClose) {logger.info('WebSocket is already connected or connecting.');return;}wx.connectSocket({url: `${this.url}/${userId}`,header: {'content-type': 'application/json'},method: 'POST'});}/*** 发送消息* @param {Object} params - 要发送的消息参数* @returns {Promise} - 返回一个 Promise,表示消息发送的结果*/send(params) {return new Promise((resolve, reject) => {const cruParams = JSON.stringify(params);if (this.isClose) {this.preParams = params;return;}logger.debug(`send---`, JSON.stringify(cruParams));wx.sendSocketMessage({data: cruParams,success: (res) => {logger.debug('sendSocketMessage', JSON.stringify(res));resolve({ res });},fail: (res) => {logger.error('sendSocketMessage', JSON.stringify(res));reject(res);},});});}/*** 关闭 WebSocket 连接*/closeConnection() {this.isClose = true;wx.closeSocket();}/*** 处理 WebSocket 错误事件*/_onSocketError() {wx.onSocketError((res) => {this.isClose = true;logger.error('WebSocket连接打开失败,请检查!', JSON.stringify(res));this.reconnect();});}/*** 处理 WebSocket 关闭事件*/_onSocketClose() {wx.onSocketClose((res) => {this.isClose = true;logger.error('WebSocket 已关闭!', JSON.stringify(res));this.reconnect();});}/*** 处理 WebSocket 打开事件*/_onSocketOpen() {wx.onSocketOpen(() => {logger.debug('WebSocket连接已打开!');this.heartCheck.reset().start();if (this.isClose && this.preParams) {logger.info('重新发送WebSocket消息!');wx.sendSocketMessage({data: JSON.stringify(this.preParams),success: () => {logger.debug('重新发送--sendSocketMessage', JSON.stringify(this.preParams));this.preParams = '';},fail: (res) => {logger.error('重新发送--sendSocketMessage-fail', JSON.stringify(res));},});} else {wx.sendSocketMessage({data: "PING",});}this.isClose = false;});}/*** 处理 WebSocket 消息事件*/_onSocketMessage() {wx.onSocketMessage((res) => {if (res.data == "PONG") {console.log('PONG成功');this.heartCheck.reset().start();}});}/*** 尝试重新连接 WebSocket*/reconnect() {if (this.lockReconnect) return;this.lockReconnect = true;clearTimeout(this.timer);if (this.limit < 50) {this.timer = setTimeout(() => {this.lockReconnect = false;}, 300);this.limit = this.limit + 1;}}
}
// 使用时
this.wsHandler = new WebSocketHandler();
app.wsHandler.send(params).then();

相关文章:

【小程序websocket最佳实践,有心跳和断线重连】

小程序websocket最佳实践&#xff0c;有心跳和断线重连 封装了WebSocketHandler类&#xff0c;用于管理websocket链接&#xff0c;保证链接的稳定和可靠&#xff0c;该类主要适用于小程序&#xff0c;但其设计思想和方法也适用于其他平台。 export default class WebSocketHa…...

自然资源部最新Nature正刊!!!

2024年8月21日&#xff0c;国际顶级期刊《Nature》发表了自然资源部第二海洋研究所李家彪院士为通讯作者&#xff0c;张涛为第一作者的论文“超慢速扩张加克洋中脊的高变化岩浆增生”。这一成果颠覆了国际海洋学术界半个多世纪以来一直认为的超慢速扩张洋中脊岩浆供给极度贫瘠的…...

git分支-创建、合并、删除

Git会将每次提交串成一条时间线&#xff0c;这条时间线就是一个分支。在最初&#xff0c;只有一个master分支 在目录下创建项目 对目录进行输入 项目被修改 创建dev分支 合并分支 删除dev分支...

Python:Spoonfed - (2-10) 激励选择脚本(搬砖)

https://www.patreon.com/posts/python-spoonfed-31572219 2019年11月15日 利用上一课的选择函数&#xff0c;我们现在可以拼凑出一些脚本&#xff08;有一些事情我们还没有解释&#xff0c;但应该很容易理解&#xff09;。以下代码将允许您选择当前所选对象的父对象、顶级对…...

VS Code Python 文件导入提示 xxx Module 不存在解决方式

VS Code Python 文件导入提示 xxx Module 不存在解决方式 引言正文如何打开 setting.json 文件引言 之前在 https://blog.csdn.net/u011699626/article/details/142612579?spm=1001.2014.3001.5501 一文中我们介绍了如何配置 VS code 中 Jupyter Notebook 的文件导入环境,这…...

Android中的Activity与Fragment:深入解析与应用场景

在Android应用开发中&#xff0c;Activity和Fragment是两个核心概念&#xff0c;它们各自扮演着不同的角色&#xff0c;共同构成了用户界面的基础。理解并熟练掌握这两个组件的使用&#xff0c;对于开发高效、灵活且用户友好的Android应用至关重要。本文将深入解析Activity与Fr…...

Flux【lora模型】【真人模型】:极致逼真,小红书真实风格|旅游拍照|景点打卡

大家好我是安琪&#xff01;&#xff01;&#xff01; 今天和大家推荐一款基于Flux训练的真人写实的lora模型&#xff1a;Flux_小红书真实风格丨日常照片丨极致逼真。一看这个模型的命名&#xff0c;就可以猜测出以小红书日常真实拍摄的照片为数据集训练而来&#xff0c;该模型…...

python基础语法--顺序结构

Python中的顺序结构主要包括流程控制语句&#xff0c;如 if、while 和 for 语句。这些语句允许你在程序中定义不同的执行路径&#xff0c;从而根据条件或循环次数来改变代码的执行流程。下面详细介绍这些语句的使用方法和示例。 if 语句 if 语句用于根据某个条件来决定是否执…...

软件游戏运行缺少vcruntime140.dll怎么办?总结四种有效简单方法

1. 文件基本信息 1.1 定义与作用 vcruntime140.dll是Microsoft Visual C 2015 Redistributable Package的一部分&#xff0c;它包含了C运行时库&#xff0c;用于支持使用Visual C开发的Windows应用程序。这个动态链接库&#xff08;DLL&#xff09;文件提供了程序执行时所需的…...

(undone) 阅读 MapReduce 论文笔记

参考&#xff1a;https://pdos.csail.mit.edu/6.824/papers/mapreduce.pdf 摘要&#xff1a;简单介绍了 MapReduce 是在大型分布式系统上工作的 Introduction 的内容总结&#xff1a; 1.介绍背景&#xff1a;为什么我们需要分布式系统&#xff1f;MapReduce 的意义是哪些 2.简…...

sql注入工具升级:自动化时间盲注、布尔盲注

项目地址&#xff1a;https://github.com/iamnotamaster/sql-injecter 给我之前写的sql注入脚本进行了一些升级&#xff0c;此文章就是对升级内容的分析&#xff0c;升级内容如下&#xff1a; 使用占位符foo来填充payload里需要经常修改的部分 自动判断循环 支持爆破和二分查…...

字节C++抖音直播一面-面经总结

1、Python和C的区别&#xff0c;Python的程序执行过程是怎样的&#xff1f;C和C呢? 解释型-编译型 不用分号-用分号 自动垃圾回收-delete 相对较慢-执行速度快 丰富的库-标注模板库 .py-解释器-字节码-PVM-输出结果 c-c with class malloc-new 标准库-STL 不重载-函数重载和…...

浅谈stm32的GPIO引脚配置模式

STM32的GPIO&#xff08;通用输入输出&#xff09;引脚可以被配置为多种模式&#xff0c;以适应不同的应用场景。下面介绍一些一些常见的STM32 GPIO引脚模式&#xff1a; 模拟输入模式&#xff08;Analog Input Mode&#xff09;&#xff1a;在这种模式下&#xff0c;GPIO引脚被…...

Meta Orion 原型的生产成本约为 10,000 美元

Orion Meta 是一项突破性的增强现实项目&#xff0c;展示了其迄今为止最先进的原型。经过多年的研究和数百万美元的开发&#xff0c;Meta 打造出了一款仅重 98 克的增强现实眼镜&#xff0c;能够将全息图投射到视线范围内的任何地方。这款眼镜由一个先进的输入系统驱动&#xf…...

MATLAB GUI设计原则与实践

MATLAB的图形用户界面&#xff08;GUI&#xff09;设计是一种强大的工具&#xff0c;用于创建交互式应用程序。良好的GUI设计不仅能够提升用户体验&#xff0c;还能提高应用程序的可用性和效率。本文将探讨MATLAB GUI设计的原则&#xff0c;并提供一些实用的代码示例。 1. GUI…...

电脑桌面显示不完整

UOS统信由于误操作&#xff0c;导致桌面放大了&#xff0c;桌面显示不完整&#xff0c;本文主要介绍如何恢复到正常的桌面。 文章目录 一、问题描述二、解决方案 一、问题描述 电脑使用过程中出现显示器只能显示部分画面&#xff0c;桌面图标异常变大&#xff0c;桌面随鼠标移…...

Spring Boot与观察者模式实现数据同步更新机制

在Spring Boot应用程序中实现观察者模式来同步更新数据是一种强大的设计方式,它可以帮助你构建响应式和松耦合的应用程序。观察者模式通常用于当一个对象的状态改变时,所有依赖于它的对象都会得到通知并自动更新。 观察者模式的基本概念 •Subject(被观察者):维护了一个…...

毕业设计选题:基于ssm+vue+uniapp的校园订餐小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…...

每日OJ题_牛客_HJ108求最小公倍数_C++_Java

目录 牛客_HJ108求最小公倍数_C_Java 题目解析 C代码 Java代码 牛客_HJ108求最小公倍数_C_Java 求最小公倍数_牛客题霸_牛客网 题目解析 A 和 B 的最小公倍数 A * B / 两者的最大公约数。最大公约数&#xff1a;辗转相除法。 C代码 #include <iostream> #includ…...

【项目总结】工程构建思路分析与分享

背景 写这篇文章的初衷是因为国产化项目临近结束&#xff0c;在做项目总结时&#xff0c;回想起了代码管理的相关问题。虽然工程搭建及管理是一个高级工程师必备的能力&#xff0c;但似乎每次一个新项目立项&#xff0c;都是从老的项目中拷贝工程框架&#xff0c;再进行定制修…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...