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 算法-动态障碍物处理、多步预测和启发式函数优化
在智能驾驶领域,D* Lite 算法是一种高效的动态路径规划算法,适用于处理环境变化时的路径重规划问题。以下将为你展示 D* Lite 算法的高级用法,包含动态障碍物处理、多步预测和启发式函数优化等方面的代码实现。 代码实现 import heapq impo…...
MySQL 8版本认证问题
目录 问题: Public Key Retrieval is not allowed原因: mysql 8.0 调整身份认证机制解决方法(三种) 问题: Public Key Retrieval is not allowed 连接MySQL8数据库的时候,报错内容如下:“Publi…...
Android 开发APP中参数配置与读取总结
以使用MQTT配置的参数 MQTT_BROKER_UR 、MQTT_USER_NAME、 MQTT_PASSWORD为例,说明配置设置和读取应用 项目中使用系统参数(如环境变量和gradle.properties文件中的属性)在Gradle构建脚本中,以下是一个详细的操作文档资料&…...
Scala 语法入门
Scala语法入门 1. 定义变量2. 定义方法3. 闭包4. 声明字符串5. 声明数组6. 声明集合7. 异常处理 1. 定义变量 (变量的类型在变量名之后等号之前声明) 不可变变量(val) 类似于 Java 中的 final 变量,即一旦赋值后,其值不能再被改…...
python中的flask框架
Flask 是一个用Python编写的轻量级Web应用框架 基于WSGI和Jinja2模板引擎 被称为“微框架”,其核心功能简单,不捆绑数据库管理、表单验证等功能,而是通过扩展来增加其他功能 Flask提供最基本的功能,不强制使用特定工具或库 通…...
【redis】缓存设计规范
本文是 Redis 键值设计的 14 个核心规范与最佳实践,按重要程度分层说明: 一、通用数据类型选择 这里我们先给出常规的选择路径图。 以下是对每个步骤的分析: 是否需要排序?: zset(有序集合)用…...
归一化与伪彩:LabVIEW图像处理的区别
在LabVIEW的图像处理领域,归一化(Normalization)和伪彩(Pseudo-coloring)是两个不同的概念,虽然它们都涉及图像像素值的调整,但目的和实现方式截然不同。归一化用于调整像素值的范围,…...
DeepSeek大模型本地部署实战
1. 下载并安装Ollama 打开浏览器:使用你常用的浏览器(如Chrome、Firefox等)访问Ollama的官方网站。无需特殊网络环境,直接搜索“Ollama”即可找到。 登录与下载:进入Ollama官网后,点击右上角的“Download…...
deepseek+kimi自动生成ppt
打开deepseek官网,输入详细的需求,让他生成个ppt 接着deepseek开始思考生成了 接着复制生成了的内容 打开kimi粘贴刚才deepseek生成的内容 可以一键生成啦,下载编辑使用吧...
集成SwanLab与HuggingFace TRL:跟踪与优化强化学习实验
文章目录 1. 引入SwanLabCallback2. 传入Trainer3. 完整案例代码4. GUI效果展示 TRL (Transformers Reinforcement Learning,用强化学习训练Transformers模型) 是一个领先的Python库,旨在通过监督微调(SFT)、近端策略优化…...
cefsharp131升级132测试(WinForms.NETCore)
一、升级(Nuget) 版本说明(readme):最低.NET Core3.1 (NET5.0) Visual C 2019 Redist 二、试运行、兼容性测试 三、后记说明 支持H264版本推荐版本63,79,84,88,100,111,125(支持h264和pdf预览) 其他H264版…...
Gitee AI上线:开启免费DeepSeek模型新时代
Gitee Al上线,并宣布开启免费DeepSeek模型的时代,这是一个非常值得关注的消息,因 为它标志着国内在AI领域的一个重要发展。DeepSeek模型是由阿里巴巴达摩院开发的,旨 在提供强大的自然语言处理(NLP)能力。下面是一些关于这一事件…...
nginx常用命令及补充
在Linux环境下nginx常用命令如下: 1、查看nginx版本号命令 nginx -v 2、查找nginx配置文件路径已经检查配置文件是否正确 nginx -t 3、查找nginx安装目录 which nginx 4、查看nginx进程 ps -ef|grep nginx 5、进入到nginx的sbin目录后,执行一下…...
自动驾驶---聊聊传统规控和端到端
1 背景 在自动驾驶领域中,端到端模型的兴起确实对传统的规划控制方法(笔者并不同意网上以Rule-Base称呼传统规控,传统的规控其实也使用了很多优化算法和博弈算法)产生了挑战,但这就意味着传统规控方法就完全没有应用了…...
node.js + html + Sealos容器云 搭建简易多人实时聊天室demo 带源码
node.js html Sealos容器云 搭建简易多人实时聊天室demo 带源码 前言功能介绍(demo演示)sealos官网配置node.js 编写服务端代码前端ui 调用接口整体项目目录部署到服务器 前言 hello哦盆友们,这次我们来十几行代码做一个超简单的多人聊天…...
OpenFeign远程调用返回的是List<T>类型的数据
在使用 OpenFeign 进行远程调用时,如果接口返回的是 List 类型的数据,可以通过以下方式处理: 直接定义返回类型为List Feign 默认支持 JSON 序列化/反序列化,如果服务端返回的是 List的JSON格式数据,可以直接在 Feig…...
PCL 计算多边形的面积【2025最新版】
目录 一、算法原理1、概述2、主要函数3、函数源码二、代码实现三、结果展示博客长期更新,本文最近更新时间为:2025年1月17日。 一、算法原理 1、概述 根据给定的多边形的点云计算多边形的面积 A r e a = 1 2 ∑...
著名大模型评测榜单(不同评测方式)
在评估大语言模型的性能时,一种主流的途径就是选择不同的能力维度并且构建对应的评测任务,进而使用这些能力维度的评测任务对模型的性能进行测试与对比。由大型机构或者研究院所排出榜单。 评测指标 不同评测任务有不同的评指标,衡量模型的…...
PyFluent:重构CFD仿真流程的技术赋能与效能跃迁
PyFluent:重构CFD仿真流程的技术赋能与效能跃迁 【免费下载链接】pyfluent 项目地址: https://gitcode.com/gh_mirrors/pyf/pyfluent 在现代工程仿真领域,计算流体动力学(CFD)技术正经历着从手动操作向自动化流程的深刻转…...
Cursor功能增强工具使用指南
Cursor功能增强工具使用指南 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your trial request limit. / Too many free t…...
计算机网络 之 【网络套接字编程】(固定宽度整数类型、socket常见API、netstat)
目录 一.固定宽度整数类型(C11引入) 二、socket 常见API socket bind IP地址绑定类型 TCP 编程模型流程图 listen accept connect UDP编程模型流程图 recvfrom 函数 sendto 函数 常用 flags 选项 常用错误码 三、netstat Linux/Unix 选项…...
UG模型转STP后总出问题?可能是STEP 203和214版本没选对
UG模型转STP格式的深度选择指南:STEP 203与214版本差异解析 在工业设计领域,UG NX与STP格式的转换堪称日常操作,但许多工程师都曾遭遇这样的困境:明明转换过程一切顺利,接收方打开文件时却出现面片丢失、PMI信息异常甚…...
从朱诺到威尼斯:一个可持续旅游模型如何‘开箱即用’解决你的美赛问题二
从朱诺到威尼斯:可持续旅游模型的跨场景迁移实战指南 模型迁移的核心挑战与解决框架 当我们将一个城市的可持续旅游模型迁移到另一个城市时,表面上看似乎只需要更换数据输入,但实际操作中会遇到三个维度的挑战: 1. 资源禀赋差异 自…...
文明降级运动:回归纸笔抵抗AI监控
在AI技术席卷软件测试领域的浪潮中,一个看似“倒退”却极具战略意义的趋势正在兴起——文明降级运动。这场运动的核心是主动回归纸笔工具,以抵抗AI监控带来的系统性风险。作为软件测试从业者,我们身处技术前沿,见证了AI在缺陷预测…...
实战构建开放数据可视化平台,从采集到展示的全流程开发指南
今天想和大家分享一个完整的开放数据可视化项目实战经验。这个项目从数据采集到最终展示,涵盖了全流程开发的关键环节,特别适合想积累真实项目经验的朋友参考。 项目背景与目标 开放数据正在成为数字化转型的重要资源,但很多开发者面对海量…...
OpenClaw多用户方案:QwQ-32B共享环境下的权限隔离
OpenClaw多用户方案:QwQ-32B共享环境下的权限隔离 1. 为什么需要多用户方案? 去年我在家里搭建了一个OpenClaw自动化环境,原本只是个人使用。直到某天家人看到我用语音指令让AI自动整理照片、生成周报后,纷纷要求"共享&quo…...
告别手动操作!用Word宏/VBA实现doc批量转docx的隐藏技巧
职场效率革命:Word宏/VBA零代码实现文档格式批量升级 每天面对堆积如山的.doc文件,行政文员小张总要手动打开每个文件另存为.docx格式——这个机械操作不仅耗时费力,还容易遗漏文件。其实微软Office内置的自动化工具能完美解决这个问题&#…...
腾讯混元翻译模型实战:跨境电商多语言商品描述生成案例
腾讯混元翻译模型实战:跨境电商多语言商品描述生成案例 1. 项目背景与价值 跨境电商企业面临一个共同挑战:如何高效地将商品信息翻译成多种语言。传统人工翻译成本高、周期长,而通用翻译工具又难以满足电商场景的专业需求。 腾讯混元翻译模…...
