前端封装websocket类,实现消息注册和全局回调

实现消息注册和回调函数,实现全局使用同一个webscoket对象,并实现断线重连和心跳连接等功能,可以实现全局使用唯一实例,可以另外进行拓展配置

// WebSocket类对象
class WebSocketCli {
    // 构造函数
    constructor(url: string, opts = {}) {
        this.url = url
        this.ws = null
        this.opts = {
            heartbeatInterval: 30000, // 默认30秒
            reconnectInterval: 5000, // 默认5秒
            maxReconnectAttempts: 5, // 默认尝试重连5次
            ...opts,
        }
        this.heartbeatInterval = 30000
        this.reconnectAttempts = 0
        this.listeners = {}
        this.init()
    }

    // 链接地址
    url: string
    // websocket实例
    ws: WebSocket | null
    // websocket配置:配置心跳和重连等信息
    opts: any
    // 重新连接次数:默认5次
    reconnectAttempts: number
    // 时间监听对象数组:可以为一个事件绑定多个监听事件
    listeners: any
    // 心跳链接间隔
    heartbeatInterval: number | null

    // 初始化ws对象
    init() {
        this.ws = new WebSocket(this.url)
        this.ws.onopen = this.onOpen.bind(this)
        this.ws.onmessage = this.onMessage.bind(this)
        this.ws.onerror = this.onError.bind(this)
        this.ws.onclose = this.onClose.bind(this)
    }

    // websocket链接建立
    onOpen(event) {
        console.log('WebSocket opened:', event)
        this.reconnectAttempts = 0 // 重置重连次数
        // 发送心跳链接
        // this.startHeartbeat()
        this.emit('open', event)
    }

    // websocket收到消息
    onMessage(event) {
        console.log('WebSocket message received:', event.data)
        this.emit('message', event.data)
    }

    // websocket错误
    onError(event) {
        console.error('WebSocket error:', event)
        this.emit('error', event)
    }

    // websocket关闭
    onClose(event) {
        console.log('WebSocket closed:', event)
        // 停止心跳链接
        // this.stopHeartbeat()
        this.emit('close', event)
        // 最大5次重连
        if (this.reconnectAttempts < this.opts.maxReconnectAttempts) {
            setTimeout(() => {
                this.reconnectAttempts++
                this.init()
            }, this.opts.reconnectInterval)
        }
    }

    // 发送心跳
    startHeartbeat() {
        this.heartbeatInterval = setInterval(() => {
            if (this.ws?.readyState === WebSocket.OPEN) {
                this.ws.send('ping') // 可以修改为你的心跳消息格式
            }
        }, this.opts.heartbeatInterval)
    }

    // 停止心跳
    stopHeartbeat() {
        if (this.heartbeatInterval) {
            clearInterval(this.heartbeatInterval)
            this.heartbeatInterval = null
        }
    }

    // 发送消息
    send(data) {
        if (this.ws?.readyState === WebSocket.OPEN) {
            this.ws.send(data)
        } else {
            console.error('WebSocket is not open. Cannot send:', data)
        }
    }

    // 注册某个消息事件,并添加回调函数
    on(event, callback) {
        if (!this.listeners[event]) {
            this.listeners[event] = []
        }
        // 将回调函数放进事件数组中
        this.listeners[event].push(callback)
    }

    // 取消某个消息:如果存在回调函数就只移除这个回调事件,不存在就清空所有
    off(event, callback?) {
        if (!this.listeners[event]) return
        const index = callback && this.listeners[event].indexOf(callback)
        if (callback && index !== -1) {
            this.listeners[event].splice(index, 1)
        } else {
            console.log('移除所有事件: ', event)
            this.listeners[event] = []
        }
    }

    // 接收到消息后,通过这个函数执行所有回调函数
    emit(event, data) {
        if (this.listeners[event]) {
            this.listeners[event].forEach((callback) => callback(data))
        }
    }
}

// 导出对象
export default WebSocketCli

使用的时候:单例模式

// 全局唯一websocket对象
const wsUrl = 'ws://192.168.1.171:9080/v1/server/webgetapi'
const wsInstance = new WebSocketCli(wsUrl)

// 导出对象
export default wsInstance

vue使用的时候,需要注意:最好不要封装到自定义hooks里面,否则可能会出现注册后的消息为空的情况:然后就会导致消息监听失效

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android悬浮窗实现步骤

最近想做一个悬浮窗秒表的功能&#xff0c;所以看下悬浮窗具体的实现步骤 1、初识WindowManager 实现悬浮窗主要用到的是WindowManager SystemService(Context.WINDOW_SERVICE) public interface WindowManager extends ViewManager {... }WindowManager是接口类&#xff0c…

如何判断 LM358 芯片是否损坏或故障?

LM358 芯片是一种流行的低功耗双运放&#xff0c;广泛应用于各种电子电路中&#xff0c;包括放大器、滤波器、积分器、比较器等。它以其低成本、高性价比和广泛的工作电源范围&#xff08;3V至32V单电源或1.5V至16V双电源&#xff09;而被广泛使用。 然而&#xff0c;像所有电…

【Docker与微服务】基础篇

1 Docker简介 1.1 docker是什么 1.1.1 问题&#xff1a;为什么会有docker出现&#xff1f; 假定您在开发一个项目&#xff0c;您使用的是一台笔记本电脑而且您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。您正在开发的应用依赖于您当前的配置且还要依…

Vue中使用定义的函数时,无法访问到data()里面的数据

const translateItems1 () > {this.translatedItems this.items1.map(item > {return {...item,label: this.$t(item.labelKey)};}); items1是我们data()里面的数据&#xff0c;无法访问到 解决办法 把箭头函数替换为普通函数 const translateItems1 function() {th…

Prometheus的监控告警

前言 alter是一个单独的模块&#xff0c;需要单独的配置 需要声明邮箱地址。配置以configmap进行配置。 altermanager也是pod部署。部署在k8s集群当中。 alertmanager设置告警邮件 apiVersion: v1 kind: ConfigMap metadata:name: alertmanagernamespace: monitor-sa data:al…

blender 画笔的衰成曲线Falloff Curve

Blender画笔是用来在雕刻模式或绘画模式下对物体进行修改的工具。画笔有不同的类型和设置&#xff0c;可以影响画笔的效果和外观。你提到的选项是画笔的衰减曲线&#xff08;Falloff Curve&#xff09;的预设&#xff0c;它们决定了画笔的强度如何随着距离中心的距离而变化。 …

【web | CTF】攻防世界 easyupload

天命&#xff1a;好像也不太easy 目录 步骤一&#xff1a;准备文件 步骤二&#xff1a;上传文件 本条题目有好几个防御点&#xff1a; 后缀名防御&#xff1a;只能上传图片格式内容防御&#xff1a;内容不能有php图片头防御&#xff1a;检测文件的头部信息&#xff0c;是否是…

LM Studio-简化安装和使用开源大模型 | OpenAI API 文字转语音本地运行程序分享

原文&#xff1a;LM Studio-简化安装和使用开源大模型 | OpenAI API 文字转语音本地运行程序分享 - 知乎 实测在Mac上使用Ollama与AI对话的过程 - 模型选择、安装、集成使用记&#xff0c;从Mixtral8x7b到Yi-34B-Chat 官网&#xff1a;https://lmstudio.ai/ 最近用上了LM St…

软件工程知识梳理6-运行和维护

软件维护需要的工作量很大&#xff0c;大型软件的维护成本高达开发成本的4倍左右。所以&#xff0c;软件工程的主要目的就是要提高软件的可维护性&#xff0c;减少软件维护所需要的工作量&#xff0c;降低软件系统的总成本。 定义&#xff1a;软件已经交付使用之后&#xff0c;…

java面向对象基础(面试)

一、面向对象基础 1. 面向对象和面向过程的区别 面向过程把解决问题的过程拆成一个个方法&#xff0c;通过一个个方法的执行解决问题。面向对象会先抽象出对象&#xff0c;然后用对象执行方法的方式解决问题。 2.创建一个对象用什么运算符?对象实体与对象引用有何不同? n…

数据防泄密方案公司(dlp数据防泄密厂商排名)

在当今数字化时代&#xff0c;数据已经成为了企业最重要的资产之一。然而&#xff0c;随着企业信息化的不断深入&#xff0c;数据泄露的风险也越来越大。为了保护企业的核心数据&#xff0c;越来越多的企业开始重视数据防泄密工作&#xff0c;并寻求专业的数据防泄密方案提供商…

4-MongoDB索引知识

4.1 概述 索引支持在MongoDB中高效地执行查询。如果没有索引&#xff0c;MongoDB必须执行全集合扫描&#xff0c;即扫描集合中的每个文档&#xff0c;以选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的&#xff0c;特别在处理大量的数据时&#xff0c;查询可以要…

api接口1688商品详情接口采集商品详情数据商品价格详情页数据可支持高并发调用演示示例

接入1688商品详情API接口的步骤如下&#xff1a; 注册账号&#xff1a;首先&#xff0c;你需要在1688开放平台注册一个账号。 创建应用&#xff1a;登录后&#xff0c;在控制台中找到“我的应用”&#xff0c;点击“创建应用”。 获取API密钥&#xff1a;创建应用后&#xff…

VSCode 设置代理

Open Visual Studio Code, click the settings icon in the lower left corner, and click Settings.

Web3.0初探

Web3.0初探 一、互联网发展史二、什么是Web3.0&#xff1f;三、现在的发展方向&#xff08;衍生出来的产品&#xff09;&#xff1a;四、目前问题五、Web3.0与元宇宙 一、互联网发展史 Web3.0也就是第三代互联网。最新版本的Web3.0是以太坊的创始合伙人Gavin Wood在2014年提出…

基于Python的货币识别技术实现

目录 介绍本文的目的和意义货币识别技术的应用场景货币识别的基本原理图像处理技术在货币识别中的应用特征提取方法:SIFT、HOG等支持向量机(SVM)分类器的使用实现过程数据集的收集和预处理特征提取和训练分类器参考文献介绍 本文的目的和意义 本文的目的是介绍如何利用Pyt…

观测云产品更新 | 告警策略、智能监控、场景图表、查看器等

观测云更新 监控 1、告警策略新增支持配置自定义时间段发送告警通知&#xff0c;您可以自由按日期、时间点配置不同的告警通知及对象&#xff0c;满足不同通知需求&#xff1b;重复告警新增【永久】这一事件选项&#xff1b; 2、新增支持配置多组告警策略&#xff0c;帮助您更…

解决:ModuleNotFoundError: No module named ‘torchvision’

解决&#xff1a;ModuleNotFoundError: No module named ‘torchvision’ 文章目录 解决&#xff1a;ModuleNotFoundError: No module named torchvision背景报错问题报错翻译报错位置代码报错原因解决方法方法一&#xff0c;直接安装方法二&#xff0c;手动下载安装方法三&…

Kotlin 协程:深入理解 ‘async { }‘

Kotlin 协程&#xff1a;深入理解 ‘async { }’ Kotlin 协程是一种强大的异步编程工具&#xff0c;它提供了一种简洁、易读的方式来处理并发和异步操作。在 Kotlin 协程库中&#xff0c;async {} 是一个关键的函数&#xff0c;它允许我们启动一个新的协程&#xff0c;并返回一…

安卓相对布局RelativeLayout

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"150dp"><TextViewandroid…