当前位置: 首页 > 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.lryc.cn/news/599669.html

相关文章:

  • TDengine 转化函数 TO_TIMESTAMP 用户手册
  • 比特币技术简史 第八章:扩展性解决方案 - 闪电网络与隔离见证
  • 软件工程:软件需求
  • Ethereum:告别 personal API,拥抱 Geth 的独立签名器 Clef
  • CRM 系统:实现商机全流程管理的关键
  • Mkdocs相关插件推荐(原创+合作)
  • 力扣Hot100疑难杂症汇总
  • Java环境配置之各类组件下载安装教程整理(jdk、idea、git、maven、mysql、redis)
  • 如何序列化和反序列化动态 XmlElement ?
  • 【SSL证书校验问题】通过 monkey-patch 关掉 SSL 证书校验
  • Linux725 磁盘阵列RAID0 RAID1
  • [python][flask]Flask-Login 使用详解
  • win通过OpenSSL生成.ssh id_rsa密钥方法
  • 基于libhv实现的TCP Client Server支持同步,异步传输 (C++11)
  • QT开发技术【串口和C++20协程,实现循环发送、暂停、恢复、停止】
  • 上位机知识篇---Jetson Nano的深度学习GPU推理
  • TCP模型,mqtt协议01 day41
  • 【算法-图论】图的存储
  • 嵌入式——C语言:指针①
  • Web攻防-业务逻辑篇密码找回重定向目标响应包检验流程跳过回显泄露验证枚举
  • Go 官方 Elasticsearch 客户端 v9 快速上手与进阶实践*
  • 深度学习day02--神经网络(前三节)
  • 安装本地python文件到site-packages
  • STM32基础知识学习笔记:ICODE、DCODE、DMA等常见名词的解释
  • 【C++详解】模板进阶 非类型模板参数,函数模板特化,类模板全特化、偏特化,模板分离编译
  • 在 .NET 中使用 Base64 时容易踩的坑总结
  • vscode npm run build打包报ELIFECYCLE
  • Linux进程深度解析(2):fork/exec写时拷贝性能优化与exit资源回收机制(进程创建和销毁)
  • 嵌入式学习的第三十五天-进程间通信-HTTP
  • 【论文阅读51】-CNN-LSTM-安全系数和失效概率预测