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 ∑...
著名大模型评测榜单(不同评测方式)
在评估大语言模型的性能时,一种主流的途径就是选择不同的能力维度并且构建对应的评测任务,进而使用这些能力维度的评测任务对模型的性能进行测试与对比。由大型机构或者研究院所排出榜单。 评测指标 不同评测任务有不同的评指标,衡量模型的…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
