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

websocket自动重连封装

websocket自动重连封装

前端代码封装

import { ref, onUnmounted } from 'vue';interface WebSocketOptions {url: string;protocols?: string | string[];reconnectTimeout?: number;
}class WebSocketService {private ws: WebSocket | null = null;private callbacks: { [key: string]: Function[] } = {};private reconnectTimeoutMs: number = 5000; // 默认5秒重连间隔constructor(private options: WebSocketOptions) { }public open(): void {this.ws = new WebSocket(this.options.url, this.options.protocols)this.ws.addEventListener('open', this.handleOpen);this.ws.addEventListener('message', this.handleMessage);this.ws.addEventListener('error', this.handleError);this.ws.addEventListener('close', this.handleClose);}public close(isActiveClose = false): void {if (this.ws) {this.ws.close();if (!isActiveClose) {setTimeout(() => this.reconnect(), this.reconnectTimeoutMs);}}}public reconnect(): void {this.open();}public on(event: 'message', callback: (data: any) => void): void;public on(event: 'open' | 'error' | 'close', callback: () => void): void;public on(event: string, callback: (...args: any[]) => void): void {if (!this.callbacks[event]) {this.callbacks[event] = [];}this.callbacks[event].push(callback);}private handleOpen = (): void => {console.log('WebSocket连接已建立');if (this.callbacks.open) {this.callbacks.open.forEach((cb) => cb());}};private handleMessage = (event: MessageEvent): void => {console.log(event,"event");const data = JSON.parse(event.data);console.log('WebSocket接收到消息:', data);if (this.callbacks.message) {this.callbacks.message.forEach((cb) => cb(data));}};private handleError = (error: Event): void => {console.error('WebSocket错误:', error);if (this.callbacks.error) {this.callbacks.error.forEach((cb) => cb(error));}};private handleClose = (): void => {console.log('WebSocket连接已关闭');if (this.callbacks.close) {this.callbacks.close.forEach((cb) => cb());if (!this.options.reconnectTimeout) {this.reconnect();}}};public send(data: any): void {if (this.ws && this.ws.readyState === WebSocket.OPEN) {this.ws.send(JSON.stringify(data));} else {console.warn('尝试发送消息时WebSocket未连接');}}
}export default function useWebSocket(options: WebSocketOptions) {const wsService = new WebSocketService(options);onUnmounted(() => {wsService.close(true);});return {open: wsService.open.bind(wsService),close: wsService.close.bind(wsService),reconnect: wsService.reconnect.bind(wsService),on: wsService.on.bind(wsService),send: wsService.send.bind(wsService)};
}

组件中使用

<script setup lang="ts">
import { onMounted } from 'vue'
import useWebSocket from "@/utils/websocket";
const os = useWebSocket({ url: 'http://localhost:3000' })const onSend = () => {os.send({ text: '你好' })
}onMounted(async () => {os.open()os.on('message', (event) => {console.log(event, "event");})
});
</script>

后端代码封装

const express = require('express');
const bodyParser = require('body-parser');
const http = require('http');
const WebSocket = require('ws');
const cors = require('cors');
const app = express();
const server = http.createServer(app);const corsOption = {origin: 'http://localhost:8088',methods: ['GET', 'POST', 'PUT', 'DELETE'],allowedHeaders: ['Content-Type', 'Authorization'],
}app.use(cors(corsOption))// 增加请求体大小限制
app.use(bodyParser.json({ limit: '100mb' }));  // 允许最多10MB的JSON数据
app.use(bodyParser.urlencoded({ limit: '100mb', extended: true }));// 初始化 WebSocket 服务器实例
const wss = new WebSocket.Server({ server });// 监听 WebSocket 连接事件
wss.on('connection', (ws) => {console.log('客户端已连接');// 监听消息ws.on('message', (message) => {console.log('收到消息:', JSON.parse(message));const postMsg = {msg: "你好"}// 回复客户端ws.send(JSON.stringify(postMsg));});// 监听关闭事件ws.on('close', () => {console.log('客户端已断开连接');});
});// 设置 Express 路由
app.get('/', (req, res) => {res.send('WebSocket Server Running');
});// 启动服务器
server.listen(3000, () => {console.log('服务器在 http://localhost:3000 运行');
});

相关文章:

websocket自动重连封装

websocket自动重连封装 前端代码封装 import { ref, onUnmounted } from vue;interface WebSocketOptions {url: string;protocols?: string | string[];reconnectTimeout?: number; }class WebSocketService {private ws: WebSocket | null null;private callbacks: { [k…...

【C语言】球球大作战游戏

目录 1. 前期准备 2. 玩家操作 3. 生成地图 4. 敌人移动 5. 吃掉小球 6. 完整代码 1. 前期准备 游戏设定:小球的位置、小球的半径、以及小球的颜色 这里我们可以用一个结构体数组来存放这些要素,以方便初始化小球的信息。 struct Ball {int x;int y;float r;DWORD c…...

人工智能D* Lite 算法-动态障碍物处理、多步预测和启发式函数优化

在智能驾驶领域&#xff0c;D* Lite 算法是一种高效的动态路径规划算法&#xff0c;适用于处理环境变化时的路径重规划问题。以下将为你展示 D* Lite 算法的高级用法&#xff0c;包含动态障碍物处理、多步预测和启发式函数优化等方面的代码实现。 代码实现 import heapq impo…...

MySQL 8版本认证问题

目录 问题&#xff1a; Public Key Retrieval is not allowed原因&#xff1a; mysql 8.0 调整身份认证机制解决方法&#xff08;三种&#xff09; 问题&#xff1a; Public Key Retrieval is not allowed 连接MySQL8数据库的时候&#xff0c;报错内容如下&#xff1a;“Publi…...

Android 开发APP中参数配置与读取总结

以使用MQTT配置的参数 MQTT_BROKER_UR 、MQTT_USER_NAME、 MQTT_PASSWORD为例&#xff0c;说明配置设置和读取应用 项目中使用系统参数&#xff08;如环境变量和gradle.properties文件中的属性&#xff09;在Gradle构建脚本中&#xff0c;以下是一个详细的操作文档资料&…...

Scala 语法入门

Scala语法入门 1. 定义变量2. 定义方法3. 闭包4. 声明字符串5. 声明数组6. 声明集合7. 异常处理 1. 定义变量 &#xff08;变量的类型在变量名之后等号之前声明&#xff09; 不可变变量(val) 类似于 Java 中的 final 变量&#xff0c;即一旦赋值后&#xff0c;其值不能再被改…...

python中的flask框架

Flask 是一个用Python编写的轻量级Web应用框架 基于WSGI和Jinja2模板引擎 被称为“微框架”&#xff0c;其核心功能简单&#xff0c;不捆绑数据库管理、表单验证等功能&#xff0c;而是通过扩展来增加其他功能 Flask提供最基本的功能&#xff0c;不强制使用特定工具或库 通…...

【redis】缓存设计规范

本文是 Redis 键值设计的 14 个核心规范与最佳实践&#xff0c;按重要程度分层说明&#xff1a; 一、通用数据类型选择 这里我们先给出常规的选择路径图。 以下是对每个步骤的分析&#xff1a; 是否需要排序&#xff1f;&#xff1a; zset&#xff08;有序集合&#xff09;用…...

归一化与伪彩:LabVIEW图像处理的区别

在LabVIEW的图像处理领域&#xff0c;归一化&#xff08;Normalization&#xff09;和伪彩&#xff08;Pseudo-coloring&#xff09;是两个不同的概念&#xff0c;虽然它们都涉及图像像素值的调整&#xff0c;但目的和实现方式截然不同。归一化用于调整像素值的范围&#xff0c…...

DeepSeek大模型本地部署实战

1. 下载并安装Ollama 打开浏览器&#xff1a;使用你常用的浏览器&#xff08;如Chrome、Firefox等&#xff09;访问Ollama的官方网站。无需特殊网络环境&#xff0c;直接搜索“Ollama”即可找到。 登录与下载&#xff1a;进入Ollama官网后&#xff0c;点击右上角的“Download…...

deepseek+kimi自动生成ppt

打开deepseek官网&#xff0c;输入详细的需求&#xff0c;让他生成个ppt 接着deepseek开始思考生成了 接着复制生成了的内容 打开kimi粘贴刚才deepseek生成的内容 可以一键生成啦&#xff0c;下载编辑使用吧...

集成SwanLab与HuggingFace TRL:跟踪与优化强化学习实验

文章目录 1. 引入SwanLabCallback2. 传入Trainer3. 完整案例代码4. GUI效果展示 TRL (Transformers Reinforcement Learning&#xff0c;用强化学习训练Transformers模型) 是一个领先的Python库&#xff0c;旨在通过监督微调&#xff08;SFT&#xff09;、近端策略优化&#xf…...

cefsharp131升级132测试(WinForms.NETCore)

一、升级&#xff08;Nuget&#xff09; 版本说明&#xff08;readme&#xff09;:最低.NET Core3.1 (NET5.0) Visual C 2019 Redist 二、试运行、兼容性测试 三、后记说明 支持H264版本推荐版本63,79,84,88,100,111,125&#xff08;支持h264和pdf预览&#xff09; 其他H264版…...

Gitee AI上线:开启免费DeepSeek模型新时代

Gitee Al上线&#xff0c;并宣布开启免费DeepSeek模型的时代&#xff0c;这是一个非常值得关注的消息&#xff0c;因 为它标志着国内在AI领域的一个重要发展。DeepSeek模型是由阿里巴巴达摩院开发的&#xff0c;旨 在提供强大的自然语言处理(NLP)能力。下面是一些关于这一事件…...

nginx常用命令及补充

在Linux环境下nginx常用命令如下&#xff1a; 1、查看nginx版本号命令 nginx -v 2、查找nginx配置文件路径已经检查配置文件是否正确 nginx -t 3、查找nginx安装目录 which nginx 4、查看nginx进程 ps -ef|grep nginx 5、进入到nginx的sbin目录后&#xff0c;执行一下…...

自动驾驶---聊聊传统规控和端到端

1 背景 在自动驾驶领域中&#xff0c;端到端模型的兴起确实对传统的规划控制方法&#xff08;笔者并不同意网上以Rule-Base称呼传统规控&#xff0c;传统的规控其实也使用了很多优化算法和博弈算法&#xff09;产生了挑战&#xff0c;但这就意味着传统规控方法就完全没有应用了…...

node.js + html + Sealos容器云 搭建简易多人实时聊天室demo 带源码

node.js html Sealos容器云 搭建简易多人实时聊天室demo 带源码 前言功能介绍&#xff08;demo演示&#xff09;sealos官网配置node.js 编写服务端代码前端ui 调用接口整体项目目录部署到服务器 前言 hello哦盆友们&#xff0c;这次我们来十几行代码做一个超简单的多人聊天…...

OpenFeign远程调用返回的是List<T>类型的数据

在使用 OpenFeign 进行远程调用时&#xff0c;如果接口返回的是 List 类型的数据&#xff0c;可以通过以下方式处理&#xff1a; 直接定义返回类型为List Feign 默认支持 JSON 序列化/反序列化&#xff0c;如果服务端返回的是 List的JSON格式数据&#xff0c;可以直接在 Feig…...

PCL 计算多边形的面积【2025最新版】

目录 一、算法原理1、概述2、主要函数3、函数源码二、代码实现三、结果展示博客长期更新,本文最近更新时间为:2025年1月17日。 一、算法原理 1、概述 根据给定的多边形的点云计算多边形的面积 A r e a = 1 2 ∑...

著名大模型评测榜单(不同评测方式)

在评估大语言模型的性能时&#xff0c;一种主流的途径就是选择不同的能力维度并且构建对应的评测任务&#xff0c;进而使用这些能力维度的评测任务对模型的性能进行测试与对比。由大型机构或者研究院所排出榜单。 评测指标 不同评测任务有不同的评指标&#xff0c;衡量模型的…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

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

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

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...