WebSocket封装

news2025/1/5 4:30:01

提示:记录工作中遇到的需求及解决办法

文章目录

  • 前言
  • 二、背景
  • 三、WebSocket
    • 3.1 什么是 WebSocket ?为什么使用他?
  • 四、封装 WebSocket
    • 4.1 Javascript 版本
    • 4.2 Typescript 版本
    • 4.3 如何使用?
  • 五、我的痛点如何处理


前言

本文将介绍 WebSocket 的封装,比如:心跳机制,重连和一些问题如何去处理


二、背景

之前,钱包相关的查询,我们是使用的轮询方案来做的,后来更新了一次需求,需要做一些实时数据统计的更新,然后顺带给钱包的余额也用长连接来做了,好,那么故事就开始了…

某天,

「老板:」 我钱怎么没了,但是我这里查账户还有。

「我的内心:」 恩?这玩意难道说… 后端没返?

和后端沟通以后,感觉是返回了的,被挤账号了?排查了一段时间以后,最终我将问题锁定在手机息屏的操作上。

因为我们是一个 「H5」 的项目,APP 是嵌套在 webview 中,所以不能操作原生的事件来处理,只能将方案控制在浏览器提供的事件来处理。

好了,接下来各位可以看我是如何处理这个问题,如果没有搞过也是可以有不少收获,也欢迎大神评论区交流其他方案。

三、WebSocket

3.1 什么是 WebSocket ?为什么使用他?

以下是百度百科中对 「WebSocket」 的定义:

WebSocket 是一种在单个 TCP 连接上进行 全双工 通信的协议。WebSocket 通信协议于2011年被 IETF 定为标准 RFC 6455,并由 RFC7936 补充规范。WebSocket API 也被 W3C 定为标准。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

「WebSocket 的关键特点」

  1. 「双向通信(Full Duplex)」
    • 客户端和服务器都可以主动发送数据,而不是像 HTTP 一样只能由客户端发起请求。
  2. 「实时性」
    • 消息可以实时传递,延迟更低,适合需要实时更新的场景。
  3. 「持久化连接」
    • 使用单个 TCP 连接完成多次数据交互,无需为每次通信重新建立连接。
  4. 「轻量级协议」
    • WebSocket 头部信息非常小,比传统 HTTP 请求的头部要轻量。
  5. 「节约资源」
    • 长连接减少了资源消耗,特别是在频繁通信的场景中。

上述中,是 AI 给我们总结的 WebSocket 的特点,接下来我们要知道我们为什么使用他,HTTP 他能不能做,他的局限性又在哪里?

「传统 HTTP 的局限性:」

  1. HTTP 是基于请求-响应模型的,客户端必须发起请求,服务器才能返回数据。
  2. 如果需要实时更新(如股票价格、在线聊天),通常需要使用轮询(Polling)或长轮询(Long Polling),这会导致:
    • 高资源消耗(频繁的连接建立和断开)。
    • 高网络流量(每次请求都包含冗长的 HTTP 头部信息)。
    • 更高的延迟(数据可能需要等待较长时间才能返回)。

其实 HTTP 是可以实现的,如果 HTTP 请求频繁三次握手和四次挥手的操作会占用大量资源,HTTP/1.1 以后开启了 「Keep-Alive (长连接)」,可以复用连接,但是实时的情况下,响应模型仍然会导致较高的延迟和资源消耗。

相比之下,WebSocket 通过一次握手建立连接以后,就可以保持双向通信,服务器可以主动推送数据,无需客户端轮询。解决了 HTTP 带来的一些痛点。

四、封装 WebSocket

我们将实现以下几个功能点:

  • 「重连」
  • 「心跳机制」
  • 「事件回调」
  • 「连接状态管理」
  • 「销毁」

4.1 Javascript 版本

class ReSocket {
   
  constructor(url, options = {
    }) {
   
    this.url = url; // WebSocket 服务器地址
    this.options = options; // 可选参数
    this.socket = null; // WebSocket 实例
    this.maxReconnectTimes = options.maxReconnectTimes || 5; // 最大重连次数
    this.reconnectTimes = 0; // 当前重连次数
    this.reconnectInterval = options.reconnectInterval || 3000; // 重连间隔时间(毫秒)
    this.isClosed = false; // 是否已关闭
    this.isOpen = false; // 是否已打开
    this.isConnect = false; // 是否已连接
    this.isReconnecting = false; // 是否正在重连
    this.isDestroyed = false; // 是否已销毁
    this.reconnectTimer = null; // 重连定时器
    this.heartbeatTimer = null; // 心跳定时器
    this.heartbeatInterval = options.heartbeatInterval || 30000; // 心跳间隔时间(默认30秒)
    this.heartbeatData = options.heartbeatData || "ping"; // 心跳数据
    this.onMessageCallback = null; // 消息接收回调
    this.onOpenCallback = null; // 连接成功回调
    this.onCloseCallback = null; // 连接关闭回调
  }


  
  // 创建WebSocket实例
  createSocket() {
   
    this.socket = new WebSocket(this.url);

    this.socket.onopen = () => {
   
      this.isOpen = true;
      this.isConnect = true;
      this.reconnectTimes = 0; // 重连次数归零
      this.startHeartbeat(); // 启动心跳机制
      if (this.onOpenCallback) this.onOpenCallback(); // 调用连接成功回调
    };

    this.socket.onmessage = event => {
   
      if (this.onMessageCallback) this.onMessageCallback(event.data); // 调用消息接收回调
    };

    this.socket.onclose = () => {
   
      this.isOpen = false;
      this.isConnect = false;
      this.stopHeartbeat(); // 停止心跳机制
      if (this.onCloseCallback) this.onCloseCallback(); // 调用连接关闭回调
      if (!this.isClosed && this.reconnectTimes < this.maxReconnectTimes) {
   
        this.reconnect(); // 尝试重连
      }
    };

    this.socket.onerror = error => {
   
      console.error("WebSocket 错误: ", error); // 错误处理
    };
  }

  // 开始连接
  connect

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

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

相关文章

经验证:将数据从索尼传输到Android的 4 种方法

概括 像Android Galaxy S20 这样的新型Android智能手机很酷&#xff0c;但除了将数据从索尼传输到Android之外。众所周知&#xff0c;旧的索尼手机上存储着大量的文件&#xff0c;因此将数据从旧的索尼手机传输到新的Android手机非常重要。为了解决这个问题&#xff0c;我们做…

VITUREMEIG | AR眼镜 算力增程

根据IDC发布的《2024年第三季度美国AR/VR市场报告》显示&#xff0c;美国市场AR/VR总出货量增长10.3%。其中&#xff0c;成立于2021年的VITURE增长速度令人惊艳&#xff0c;同比暴涨452.6%&#xff0c;成为历史上增长最快的AR/VR品牌。并在美国AR领域占据了超过50%的市场份额&a…

JavaSpring AI与阿里云通义大模型的集成使用Java Data Science Library(JDSL)进行数据处理

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…

git reset --hard(重置到当前提交,所有未提交的更改都会被永久丢弃)

git reset --hard 是一个强大的命令&#xff0c;它会将你的工作目录、暂存区和当前分支的 HEAD 指针重置到指定的提交状态&#xff0c;所有未提交的更改都会被永久丢弃。因此&#xff0c;使用这个命令时需要非常小心。 基本用法 重置到当前提交&#xff08;丢弃所有未提交的更…

基于单片机智能水产养殖系统设计(论文+源码)

1 系统方案设计 根据系统设计需求&#xff0c;对智能水产养殖系统总体方案展开详细设计。如图2.1所示为系统设计总框架&#xff0c;系统以STM32单片机作为主控制器&#xff0c;通过DS18B20温度传感器、水位传感器、TSW-30浊度传感器、光照传感器实现水产养殖环境中水温、水位、…

基于微信小程序的校园点餐平台的设计与实现(源码+SQL+LW+部署讲解)

文章目录 摘 要1. 第1章 选题背景及研究意义1.1 选题背景1.2 研究意义1.3 论文结构安排 2. 第2章 相关开发技术2.1 前端技术2.2 后端技术2.3 数据库技术 3. 第3章 可行性及需求分析3.1 可行性分析3.2 系统需求分析 4. 第4章 系统概要设计4.1 系统功能模块设计4.2 数据库设计 5.…

Mysql学习笔记之约束

1.简介 MySQL中的约束用于定义表中数据的规则&#xff0c;以确保数据的准确性和完整性。以保证数据表中数据的有效性、正确性和完整性。 2.约束分类 在mysql中约束分类如下&#xff1a; 约束说明关键字主键约束每个表只能有一个主键&#xff1b;主键的值必须唯一&#xff0…

LabVIEW 实现自动对焦的开发

自动对焦&#xff08;Autofocus, AF&#xff09;技术是通过分析图像或传感器信号&#xff0c;动态调整焦点位置以实现清晰成像或高精度定位的过程。在LabVIEW中&#xff0c;可以通过集成信号采集、数据处理、控制算法和硬件接口模块&#xff0c;实现多种自动对焦方法&#xff0…

2024年第52周ETF周报

ETF 第52 周 &#xff08; 2024-12-23 至 2024-12-29 &#xff09;周报 核心观点 ETF 业绩表现 股票型ETF周度收益率中位数为1.0731%宽基ETF中&#xff0c;科创创业50涨跌幅中位数为1.5625%&#xff0c;跌幅最小。按板块划分&#xff0c;金融涨跌幅中位数为1.9334%&#xff…

[Qt] 万字详解Qt入门~ Qt Creator | 对象树 | 控件布局

目录 1. Qt Creator 概览 2. 使用 Qt Creator 新建项目 3. 认识 Qt Creator 界面 4. Qt Hello World 程序 1. 使用 “按钮” 实现 2. 使用 “标签” 实现 3. 使用 “编辑框” 实现 5. 项目文件解析 1. 命名空间声明与作用 2. class Widget : public QWidget 6. Qt 编…

远程命令执行之基本介绍

一.远程命令执行漏洞 1.命令执行 命令执行是指计算机程序接受用户输入的命令&#xff0c;并按照命令的要求执行相应的操作。命令可以执行各种操作&#xff0c;例如读取文件、创建文件、修改文件、运行程序、删除文件等。 命令执行通常是通过一个命令行界面或终端窗口进行的。在…

【数据结构-单调队列】力扣2762. 不间断子数组

给你一个下标从 0 开始的整数数组 nums 。nums 的一个子数组如果满足以下条件&#xff0c;那么它是 不间断 的&#xff1a; i&#xff0c;i 1 &#xff0c;…&#xff0c;j 表示子数组中的下标。对于所有满足 i < i1, i2 < j 的下标对&#xff0c;都有 0 < |nums[i1…

扩充vmware磁盘大小以及分区

扩充vmware磁盘大小以及分区 扩充vmware磁盘大小 分区 目前使用vmware版本为17.5.2 gparted fdisk cxqubuntu:~$ sudo fdisk -l Disk /dev/loop0: 219 MiB, 229638144 bytes, 448512 sectors Units: sectors of 1 * 512 512 bytes Sector size (logical/physical): 512 …

【Python图像处理】进阶实战续篇(七)

在上一篇文章中&#xff0c;我们探讨了Python在图像处理中的几个前沿技术&#xff0c;包括语义分割和视频帧间插值。本篇将继续深化这些话题&#xff0c;并进一步拓展到其他相关的高级技术应用中&#xff0c;以便为读者提供更为详尽的知识体系。 12. 深度学习在语义分割中的应…

TIOBE 指数 12 月排行榜公布,VB.Net排行第九

IT之家 12 月 10 日消息&#xff0c;TIOBE 编程社区指数是一个衡量编程语言受欢迎程度的指标&#xff0c;评判的依据来自世界范围内的工程师、课程、供应商及搜索引擎&#xff0c;今天 TIOBE 官网公布了 2024 年 12 月的编程语言排行榜&#xff0c;IT之家整理如下&#xff1a; …

从零开始开发纯血鸿蒙应用之UI封装

从零开始开发纯血鸿蒙应用 一、题引二、UI 组成三、UI 封装原则四、实现 lib_comps1、封装 UI 样式1.1、attributeModifier 属性1.2、自定义AttributeModifier<T>类 2、封装 UI 组件 五、总结 一、题引 在开始正文前&#xff0c;为了大家能够从本篇博文中&#xff0c;汲…

ChatBI来啦!NBAI 正式上线 NL2SQL 功能

NebulaAI 现已正式上线 NL2SQL 功能&#xff0c;免费开放使用&#xff01; 什么是 NL2SQL&#xff1f;NL2SQL 即通过自然语言交互&#xff0c;用户可以轻松查询、分析和管理数据库中的数据&#xff08;ChatBI&#xff09;&#xff0c;从此摆脱传统复杂的数据库操作。 欢迎免费…

UE5材质节点Frac/Fmod

Frac取小数 Fmod取余数 转场效果 TimeMultiplyFrac很常用 Timesin / Timecos 制作闪烁效果

二叉树的三种遍历方式以及示例图

二叉树的三种基本遍历方式是前序遍历&#xff08;Pre-order Traversal&#xff09;、中序遍历&#xff08;In-order Traversal&#xff09;和后序遍历&#xff08;Post-order Traversal&#xff09;。这三种遍历方式各有特点&#xff0c;适用于不同的场景。下面是每种遍历方式的…

数据表中列的完整性约束概述

文章目录 一、完整性约束概述二、设置表字段的主键约束三、设置表字段的外键约束四、设置表字段的非空约束五、设置表字段唯一约束六、设置表字段值自动增加七、设置表字段的默认值八、调整列的完整性约束 一、完整性约束概述 完整性约束条件是对字段进行限制&#xff0c;要求…