socket连接封装

效果:
在这里插入图片描述

class websocketMessage {
  constructor(params) {
    this.params = params; // 传入的参数
    this.socket = null;
    this.lockReconnect = false; // 重连的锁
    this.socketTimer = null; // 心跳
    this.lockTimer = null; // 重连
    this.timeout = 3000; // 发送消息
    this.callbacks = []; // 存储外部的回调函数
    // this.init(); // websocket 初始化
  }

  /**
   * @description: websocket 初始化
   * @return {*}
   */
  init() {
    if (!("WebSocket" in window)) {
      console.warn("当前浏览器不支持 WebSocket");
      return;
    }

    this.lockReconnect = false;
    this.socket = new WebSocket(this.params.ws);
    this.socket.onopen = this.open.bind(this);
    this.socket.onmessage = this.onMessage.bind(this);
    this.socket.onerror = this.error.bind(this);
    // this.socket.onclose = this.close.bind(this);
  }

  /**
   * @description: websocket 已连接
   * @return {*}
   */
  open() {
    console.log(`${this.params.ws}:WebSocket已连接。`);
  }

  /**
   * @description: 监听接收消息
   * @param {*} event
   * @return {*}
   */
  onMessage({
    data
  }) {


    // 判断是否开启心跳
    if (this.params.heart) {
      this.socketTimer && clearTimeout(this.socketTimer);
      this.socketTimer = setTimeout(() => {
        this.socket.send(JSON.stringify(this.params.heart.data));
      }, 3000);
    }

    // 如果开启心跳,过滤掉心跳的数据
    if (data === this.params?.heart?.data) {
      return;
    }
    // 将消息传递给所有注册的回调函数
    this.callbacks.forEach((callback) => callback(typeof data === 'string' ? data : JSON.parse(data)));
  }

  /**
   * @description: 注册消息回调函数
   * @param {*} callback 回调函数
   * @return {*}
   */
  message(callback) {
    if (typeof callback === "function") {
      this.callbacks.push(callback);
    } else {
      console.warn("注册的回调必须是一个函数");
    }
  }

  /**
   * @description: 发送消息
   * @param {*} msg
   * @return {*}
   */
  send(msg) {
    if (!this.socket) {
      return;
    }
    let timer = null;
    clearTimeout(timer);
    timer = setTimeout(() => {
      if (this.socket?.readyState === 1) {
        this.socket.send(JSON.stringify(msg));
        clearTimeout(timer);
      } else {
        this.send(msg);
      }
    }, 50);
  }

  /**
   * @description: 连接发送错误的时候,输出信息
   * @param {*} e 错误消息
   * @return {*}
   */
  error(e) {
    this.socket = null;
    console.log(`${this.params.ws}:WebSocket正在重新连接`, e);
    this.reconnect();
  }

  /**
   * @description: 关闭 websocket 连接
   * @return {*}
   */
  close() {
    this.socket = null;
    this.lockReconnect = true;
    this.callbacks = []; // 清除回调
    clearTimeout(this.lockTimer);
    clearTimeout(this.socketTimer);
    this.socket?.onclose();
    console.log(`${this.params.ws}:WebSocket连接已关闭`);
  }

  /**
   * @description: 重新连接 websocket
   * @return {*}
   */
  reconnect() {
    if (this.lockReconnect) {
      return;
    }
    this.lockReconnect = true;
    clearTimeout(this.lockTimer);
    this.lockTimer = setTimeout(() => {
      this.init();
    }, this.timeout);
  }
}



// 调用:
let socket = new websocketMessage({
  ws: "wss://toolin.cn/echo",
});

socket.init();

// 注册消息处理回调
socket.message((data) => {
  console.log("接收到的消息:", data);
});

// 发送登录消息
socket.send({
  type: "login",
  data: {
    userId: "123",
  },
});
setTimeout(() => {

  // 发送登录消息
  socket.send({
    type: "sadfasd",
    data: {
      userId: "sadf",
    },
  });
}, 5000)
setTimeout(() => {

  // 发送登录消息
  socket.send({
    type: "20000",
    data: {
      userId: "2",
    },
  });
}, 2000)


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

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

相关文章

基于RM开发板32学习日记

环境配置 芯片选型 STM32F407IGH6 配置时钟 12 168 模块 Led 引脚选择 比对原理图 可查看 设置为Out_Put输出 三色同时点亮 合为白色光 HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOH, GPIO_PIN_10, GPIO_PIN_SET);GPIOH->ODR…

MacOS下的Opencv3.4.16的编译

前言 MacOS下编译opencv还是有点麻烦的。 1、Opencv3.4.16的下载 注意,我们使用的是Mac,所以ios pack并不能使用。 如何嫌官网上下载比较慢的话,可以考虑在csdn网站上下载,应该也是可以找到的。 2、cmake的下载 官网的链接&…

刷题笔记15

问题描述 小M和小F在玩飞行棋。游戏结束后,他们需要将桌上的飞行棋棋子分组整理好。现在有 N 个棋子,每个棋子上有一个数字序号。小M的目标是将这些棋子分成 M 组,每组恰好5个,并且组内棋子的序号相同。小M希望知道是否可以按照这…

stm32 指定变量存储地址

uint8_t array[10] attribute((at(0x20000000))) 当你使用 attribute((at(地址))) 强制将变量放置在特定地址时,编译器和链接器通常不会自动调整其他变量的地址以避免冲突。这意味着,如果指定的地址已经被其他变量占用,就会发生冲突。 如果…

性能超越Spark 13.3 倍,比某MPP整体快数十秒 | 多项性能指标数倍于主流开源引擎 | 云器科技发布性能测试报告

云器Lakehouse正式发布性能测试报告 🏅离线批处理:在复杂批处理任务中,云器Lakehouse相较Spark表现出13.31倍性能提升。 🏅即席查询:在交互式分析场景下,云器Lakehouse相较Trino表现出9.84倍性能提升。 &am…

NIST 发布后量子密码学转型战略草案

美国国家标准与技术研究所 (NIST) 发布了其初步战略草案,即内部报告 (IR) 8547,标题为“向后量子密码标准过渡”。 该草案概述了 NIST 从当前易受量子计算攻击的加密算法迁移到抗量子替代算法的战略。该草案于 2024 年 11 月 12 日发布,开放…

论文阅读——Performance Evaluation of Passive Tag to Tag Communications(一)

文章目录 摘要一、互耦对监听器标签输入阻抗的影响A. 无限细偶极子互阻抗的理论研究B. 电细偶极子的情况:理论与模拟C. 印刷偶极子的情况:电磁模拟与测量 二、T2T 通信系统的性能评估总结 论文来源:https://ieeexplore.ieee.org/document/970…

IT人员面试重点底层逻辑概念

arrayList的底层原理 ArrayList是个动态数组,实现List接口,主要用来存储数据,如果存储基本类型的数据,如int,long,boolean,short,byte,那只存储它们对应的包装类。 它的…

PyTorch 分布式并行计算

0. Abstract 使用 PyTorch 进行多卡训练, 最简单的是 DataParallel, 仅仅添加一两行代码就可以使模型在多张 GPU 上并行地计算. 但它是比较老的方法, 官方推荐使用新的 Distributed Data Parallel, 更加灵活与强大: 1. Distributed Data Parallel (DDP) 从一个简单的非分布…

基于MATLAB的超宽带(UWB)信号的仿真和测试系统

基于MATLAB的超宽带(UWB)信号的仿真和测试系统 引言 随着无线通信技术的发展,超宽带(Ultra-Wideband, UWB)技术因其高数据传输速率、低功耗、抗多径衰落等优点而受到广泛关注。UWB技术适用于短距离高速数据传输,如个人区域网络、…

美团面试:有哪些情况会产生死锁

前言 我们首先需要知道,死锁一定发生在并发场景中。为了保证线程安全,有时会给程序使用各种能保证并发安全的工具,尤其是锁,但是如果在加解锁过程中处理不恰当,就有可能适得其反,导致程序出现死锁的情况。…

如何在Linux上安装Canal同步工具

1. 下载安装包 所用到的安装包 canal.admin-1.1.4.tar.gz 链接:https://pan.baidu.com/s/1B1LxZUZsKVaHvoSx6VV3sA 提取码:v7ta canal.deployer-1.1.4.tar.gz 链接:https://pan.baidu.com/s/13RSqPinzgaaYQUyo9D8ZCQ 提取码:…

百度主动推送可以提升抓取,它能提升索引量吗?

站长在建站SEO的时候,需要用到百度站长平台(资源平台)的工具,在站长工具中【普通收录】-【资源提交】-【API提交】这个功能,对网站的抓取进行一个提交。 这里估计很多站长就有疑问,如果我主动推送&#xf…

如何将Latex的文章内容快速用word+Endnote排版

1 第一步 Endnote文件是无法直接导入bib文件的。需要将reference.bib的参考文献内容,通过JabRef软件打开并另存为refefence.ris文件 下载JabRef软件:https://www.jabref.org/#download 导出为ris格式文件 2 第二步 通过Endnote导入ris文件&#xff0…

Telegram bot Mini-App开发实践---Telegram简单介绍与初始化小程序获取window.Telegram.WebApp对象并解析

➡️【好看的灵魂千篇一律,有趣的鲲志一百六七!】- 欢迎认识我~~ 作者:鲲志说 (公众号、B站同名,视频号:鲲志说996) 科技博主:极星会 星辉大使 后端研发:java、go、python、TS,前电商、现web3 主理人:COC杭州开发者社区主理人 、周周黑客松杭州主理人、 AI爱好…

Hadoop 系列 MapReduce:Map、Shuffle、Reduce

文章目录 前言MapReduce 基本流程概述MapReduce 三个核心阶段详解Map 阶段工作原理 Shuffle 阶段具体步骤分区(Partition)排序(Sort)分组(Combine 和 Grouping) Reduce 阶段工作原理 MapReduce 应用场景Map…

英文版本-带EXCEL函数的数据分析

一、问题: 二、表格内容 三、分析结果 四、具体的操作步骤: 销售工作表公式设计与数据验证 类别(Category)列公式: 在Category列(假设为D列),根据ProductCode在Catalogue工作表中查找…

Jmeter数据库压测之达梦数据库的配置方法

目录 1、概述 2、测试环境 3、数据库压测配置 3.1 安装jmeter 3.2 选择语言 3.3 新建测试计划 3.4 配置JDBC连接池 3.5 配置线程组 3.6 配置测试报告 3.7 执行测试 1、概述 Jmeter是Apache组织开发的基于Java的压力测试工具,用于对软件做压力测试。 它最…

Cmakelist.txt之win-c-udp-client

1.cmakelist.txt cmake_minimum_required(VERSION 3.16) ​ project(c_udp_client LANGUAGES C) ​ add_executable(c_udp_client main.c) ​ target_link_libraries(c_udp_client wsock32) ​ ​ include(GNUInstallDirs) install(TARGETS c_udp_clientLIBRARY DESTINATION $…

02:spring之AOP

一:AOP 简介 1:AOP的概念 AOP,Aspect Oriented Programming,面向切面编程,是对面向对象编程OOP的升华。OOP是纵向对一个事物的抽象,一个对象包括静态的属性信息,包括动态的方法信息等。而AOP是…