有效封装一个 WebSocket 供全局使用

server/2025/3/14 22:19:58/

前言

在现代 Web 应用中,实时通信已经成为越来越重要的一部分。而 WebSocket 技术的出现,使得实时通信变得更加高效和便捷。

WebSocket 协议是一种基于 TCP 协议的双向通信协议,它能够在客户端和服务器之间建立起持久性的连接,从而实现实时通信。

在前端开发中,为了更好地利用 WebSocket 技术,我们通常会对其进行封装,以便于全局调用并根据自己的业务做不同的预处理。

本文将介绍如何有效封装一个 WebSocket 供全局使用,并根据自己的业务做不同的预处理,实现更方便的调用,减少重复代码。

具体实现思想

我们将基于 Web API 提供的 WebSocket 类,封装一个 Socket 类,该类将提供以下功能:

  1. 建立 WebSocket 连接,并支持发送 query 参数。

  2. 发送、接收消息,支持对 WebSocket 的事件进行监听。

  3. 断开 WebSocket 连接。

  4. 支持心跳检测。

  5. 可以根据业务需要,对发送和接收的消息进行预处理。

接下来我们从实际使用的角度解释一下上面的代码,首先我们暴露了一个 useSocket 函数,该函数接收一个 options 配置项参数,支持的参数有:

  • url:要连接的 WebSocket URL;

  • protocols:一个协议字符串或者一个包含协议字符串的数组;

  • query:可以通过 URL 传递给后端的查询参数;

  • greet:心跳检测的打招呼信息;

  • customBase:自定义的 baseURL ,否则默认使用环境变量中定义的 env.VITE_APP_BASE_WS

在调用该函数后,我们首先会判断当前用户的浏览器是否支持 WebSocket,如果不支持给予用户提示。

然后我们实例化了一个 EventMap 类的实例对象 dep,你可以把它当作是一个依赖收集桶,当用户订阅了某个 WebSocket 事件时,我们将收集这个事件对应的回调作为依赖,在事件触发时,再通知该依赖,然后调用该事件对应的回调函数。

接下来我们定义了一个初始的重连次数记录值 reconnectCount 为 0,每当这个 WebSocket 重连时,该值会自增。

之后我们实例化了自己封装的 Socket 类,并传入了我们上面的三个参数。 在 Socket 类的构造函数 constructor 中,我们先取出配置项,把 query 内的参数拼接在 URL 上,然后使用 super 调用父类的构造函数进行建立 WebSocket 连接。

之后我们缓存了当前 Socket 实例化时的参数,再调用 initSocket() 方法去进行 WebSocket 事件的监听:

  • onopen:触发 dep 内 open 对应的回调函数并且打开心跳检测;

  • onclose:触发 dep 内 close 对应的回调函数并且对关闭的 code 码进行判断,如果是非正常关闭连接,将会进行重连,如果重连次数达到阈值,则通知给用户;

  • onerror:触发 dep 内 error 对应的回调函数;

  • onmessage:接收到服务端返回的数据,可以先根据自身业务做一些预处理,比如我就根据不同的数据类型进行了数据解析的预处理,之后再触发 dep 内 message 对应的回调函数并传入处理过后的数据。

我们也暴露了一些成员方法以供实例对象使用:

  • subscribe:订阅 WebSocket 事件,传入事件类型并须是 EventTypes 内的类型之一,第二个参数则是回调函数;

  • sendMessage`:同样的,我们在给服务端发送数据之前也可以根据自身业务做一些预处理,比如我将需要转成 JSON 的数据,在这里统一转换后再发送给服务端;

  • closeSocket:关闭 WebSocket 连接;

  • heartCheckStart:开始心跳检测,会创建一个定时器,在一定时间之后(默认是 55s)给服务端发送信息确认连接是否正常;

  • clearHeartCheck:清除心跳检测定时器(如果当前 WebSocket 连接已经关闭,则自动清除);

  • resetHeartCheck:重置心跳检测定时器。

实践

为了封装一个 WebSocket 类供全局使用,我们可以创建一个 Socket 类,提供必要的方法和功能。以下是一个简化的示例代码,展示了如何实现这个类:

// websocket.js
class Socket {constructor(options) {this.url = options.url;this.protocols = options.protocols;this.query = options.query;this.greet = options.greet;this.reconnectCount = 0;this.initSocket();}initSocket() {this.socket = new WebSocket(this.url);this.socket.onopen = () => {console.log(this.greet);// ... 触发 open 事件的回调 ...};this.socket.onclose = (event) => {// ... 处理关闭事件 ...if (event.code !== 1000) {// 非正常关闭this.reconnect();}};this.socket.onerror = (error) => {// ... 处理错误事件 ...};this.socket.onmessage = (message) => {// ... 处理接收到的消息 ...};}reconnect() {this.reconnectCount++;// ... 实现重连逻辑 ...}sendMessage(data) {this.socket.send(JSON.stringify(data));}closeSocket() {this.socket.close();}heartCheckStart() {// ... 实现心跳检测 ...}clearHeartCheck() {// ... 清除心跳检测定时器 ...}resetHeartCheck() {// ... 重置心跳检测定时器 ...}
}// 导出 Socket 类
export default Socket;

说明

  1. 构造函数:接收配置选项并初始化 WebSocket 连接。

  2. 事件处理:处理 onopenoncloseonerroronmessage 事件。

  3. 重连机制:在连接关闭时,如果不是正常关闭,则尝试重连。

  4. 消息发送:提供 sendMessage 方法以发送消息。

  5. 心跳检测:提供心跳检测相关的方法。

你可以根据具体需求进一步扩展和修改这个类。


http://www.ppmy.cn/server/174995.html

相关文章

鸿蒙Next开发与实战经验总结

文章目录 1. 鸿蒙Next概述与开发环境搭建1.1 鸿蒙Next的核心特性1.2 开发环境搭建与工具链安装步骤工具链 1.3 第一个鸿蒙Next应用代码示例流程图 2. 鸿蒙Next应用架构与设计模式2.1 应用架构解析2.2 常用设计模式2.3 组件化开发实践 3. UI开发与布局系统3.1 基础UI组件3.2 布局…

在CentOS系统上安装Conda的详细指南

前言 Conda 是一个开源的包管理系统和环境管理系统,广泛应用于数据科学和机器学习领域。本文将详细介绍如何在 CentOS 系统上安装 Conda,帮助您快速搭建开发环境。 准备工作 在开始安装之前,请确保您的 CentOS 系统已经满足以下条件&#x…

图论的基础知识:平凡图、简单图、连通图、平面图、完全图、对偶图、同构图

一、平凡图 平凡图是图论中最简单的图,其定义如下: 平凡图(Trivial Graph):仅包含一个顶点且没有任何边的图。 也就是说,一个平凡图满足: 顶点集合 ( V ) 的大小为 1(即 (|V| 1…

Spring Boot 项目部署启动异常问题分析与解决​:主类缺失与依赖冲突的分析

Spring Boot 项目部署启动异常问题分析与解决 在近期的 Spring Boot 项目部署工作中,遭遇了一起典型的启动异常状况。经过多维度的深入排查以及细致的调试,最终确定问题的根源在于打包插件配置与依赖管理的综合影响。以下将详细阐述整个问题的分析过程以及对应的解决办法。 …

30天学习Java第四天——设计模式

设计模式概述 设计模式是一套被广泛接受的、经过试验的、可反复使用的基于面向对象的软件设计经验总结,它是开发人员在软件设计时,对常见问题的解决方案的总结和抽象。 一句话就是,设计模式是针对软件开发中常见问题和模式的通用解决方案。 …

算法每日一练 (11)

💢欢迎来到张胤尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 算法每日一练 (11)全排列题目描述解题思路解题代码c/c…

Android Compose Paging3用法

一、引入包 implementation(libs.paging.runtime)implementation(libs.paging.compose) paging-runtime { module "androidx.paging:paging-runtime", version.ref "paging_version" } paging-compose{module"androidx.paging:paging-compose&quo…

【病毒分析】熊猫烧香病毒分析及其查杀修复

目录 前言 一、样本概况 1.1 样本信息 1.2 测试环境及工具 1.3 分析目标 二、具体行为分析 2.1 主要行为 2.1.1 恶意程序对用户造成的危害 2.2 恶意代码分析 2.2.1 加固后的恶意代码树结构图(是否有加固) 2.2.2 恶意程序的代码分析片段 三、解决方案(或总结) 3.1 …