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

vue3单页面连接多个websocket并实现断线重连功能

需求:需要在单页面中创建多个websocket并且互不影响,并实现断线重连机制,在网上看了很多文章,也下了几个插件,最后实现,在这里我不推荐使用vue-native-websocket-vue3,我看官方文档和案例,没看到怎么连接多个的,所以放弃了,socket.io-client也试过了,是需要后端要下载socket.io?放弃了,最后实现如下要求:

  1. vue3+pinia实现封装websocket
  2. 单页面可调用多个websocke连接并互不影响
  3. 设置重连机制,并设置最大重连数

1.效果

1.1设置断线重连(设置最大重连数为5),效果如下

1.2发送消息

1.3连接多个

 

2.完整代码

2.1封装websocke

// stores/websocketStore.js
import { defineStore } from 'pinia'export const useWebSocketStore = defineStore('websocket', {state: () => ({connections: {},defaultReconnectAttempts: 3,//默认最大重连次数defaultReconnectInterval: 5000,//重连间隔}),actions: {// 连接connect({ key, url, onMessage, options = {} }) {// 如果已存在相同key的连接,先关闭if (this.connections[key]) {this.disconnect(key)}const reconnectAttempts = options.reconnectAttempts ?? this.defaultReconnectAttemptsconst reconnectInterval = options.reconnectInterval ?? this.defaultReconnectIntervalconst connection = {instance: null,url,onMessage,options,reconnectCount: 0, // 当前重连次数maxReconnectAttempts: reconnectAttempts,reconnectInterval,reconnectTimer: null}this.createWebSocket(key, connection)this.connections[key] = connection},// 创建WebSocket实例(用于初始连接和重连)createWebSocket(key, connection) {connection.instance = new WebSocket(connection.url)connection.instance.onopen = () => {console.log(`WebSocket ${key} connected`)connection.reconnectCount = 0 // 重置重连计数器}connection.instance.onmessage = (event) => {if (typeof connection.onMessage === 'function') {connection.onMessage(event.data)}}connection.instance.onclose = (event) => {if (event.wasClean) {console.log(`WebSocket ${key} closed cleanly`)} else {this.handleReconnect(key)}}connection.instance.onerror = (error) => {console.error(`WebSocket ${key} error:`, error)connection.instance.close() // 触发onclose}},// 处理重连handleReconnect(key) {const connection = this.connections[key]if (!connection) returnif (connection.reconnectCount < connection.maxReconnectAttempts) {connection.reconnectCount++// 尝试重新连接日志console.log(`Attempting to reconnect ${key} (${connection.reconnectCount}/${connection.maxReconnectAttempts})`)connection.reconnectTimer = setTimeout(() => {if (connection.instance) {connection.instance.close()connection.instance = null}// 重新创建WebSocket实例而不重置计数器this.createWebSocket(key, connection)}, connection.reconnectInterval)} else {// 最大重连尝试次数 reachedconsole.log(`Max reconnection attempts (${connection.maxReconnectAttempts}) reached for ${key}`)}},// 关闭单个连接disconnect(key) {if (this.connections[key]) {const connection = this.connections[key]if (connection.instance) {connection.instance.close()}if (connection.reconnectTimer) {clearTimeout(connection.reconnectTimer)}delete this.connections[key]console.log(`WebSocket ${key} disconnected`)}},// 发送消息send(key, data) {const connection = this.connections[key]if (connection?.instance?.readyState === WebSocket.OPEN) {connection.instance.send(JSON.stringify(data))} else {console.error(`WebSocket ${key} is not connected`)}},// 关闭所有连接disconnectAll() {Object.keys(this.connections).forEach(key => {this.disconnect(key)})}}
})

2.2页面调用

调用多个websocke连接

import { useWebSocketStore } from "@/stores/websocketStore.js";// // 获取store
const websocketStore = useWebSocketStore();
const messages1 = ref([]);
const messages2 = ref([]);
const connectSocket1 = () => {websocketStore.connect({key: "socket1",url: "wss://aa.websocket.bb", // 测试用的WebSocket服务onMessage: (data) => {messages1.value.push(data);console.log("Socket1 received:", data);},options: {reconnectAttempts: 5, // 自定义重试次数reconnectInterval: 3000, // 自定义重试间隔},});
};const connectSocket2 = () => {websocketStore.connect({key: "socket2",url: "wss://bb.websocket.cc", // 另一个WebSocket服务onMessage: (data) => {messages2.value.push(data);console.log("Socket2 连接状态:", data);},});
};
// 生命周期钩子
onMounted(() => {connectSocket1();connectSocket2();
});

2.3断开所有连接

const disconnectAll = () => {websocketStore.disconnectAll();
};
// 组件卸载时断开所有连接
onUnmounted(() => {disconnectAll();
});

2.4断开单个连接

const disconnectSocket1 = () => {websocketStore.disconnect("socket1");
};

2.5发送消息

const sendDataWebsocket = () => {websocketStore.send("socket1", "Hello, World!");
};

文章到此结束,希望对你有所帮助~

 

http://www.dtcms.com/a/297654.html

相关文章:

  • 机器学习笔记(三)——决策树、随机森林
  • Git指令
  • git将本地文件完和仓库文件目录完全替换-------还有将本地更新的文件放到仓库中,直接提交即可
  • C# WPF 实现读取文件夹中的PDF并显示其页数
  • STM32与ADS1220多通道采样数据
  • vscode 登录ssh记住密码直接登录设置
  • GPU 服务器ecc报错处理
  • 详谈OSI七层模型和TCP/IP四层模型以及tcp与udp为什么是4层,http与https为什么是7层
  • SQL 查询与自定义管理工具设计:释放数据底层价值
  • linux C — udp,tcp通信
  • Docker技术入门与实战(附电子书资料)
  • 第七章 愿景10 小杨的立项课
  • 【Practical Business English Oral Scene Interpretation】入职面试No.8~9
  • [NLP]UPF+RTL联合仿真的VCS命令及UPF-aware 波形工具的使用
  • 练习实践-基础设施-文件共享-windows和linux之间的文件共享-smb服务搭建
  • 开发笔记 | 优化对话管理器脚本与对话语音的实现
  • Day 21: 常见的降维算法
  • 5G基站信号加速器!AD8021ARZ-REEL7亚德诺 超低噪声高速电压放大器 专利失真消除技术!
  • Web前端:JavaScript Math对象应用 随机背景颜色生成器
  • 【STM32项目】智能家居(版本1)
  • 关于“PromptPilot”
  • 详解:YOLO 系列演进趋势
  • 计算机网络(第八版)— 第2章课后习题参考答案
  • day 35打卡
  • 图像梯度处理与边缘检测
  • Firefox 国际版关于标签页的一些常用设置
  • 电商数据采集API与爬虫技术结合的全网比价方案
  • 【Java、C、C++、Python】飞机订票系统---文件版本
  • 北斗短报文兜底、5G-A增强:AORO P1100三防平板构建应急通信网络
  • 【Agent】API Reference Manual(API 参考手册)