vue3单页面连接多个websocket并实现断线重连功能
需求:需要在单页面中创建多个websocket并且互不影响,并实现断线重连机制,在网上看了很多文章,也下了几个插件,最后实现,在这里我不推荐使用vue-native-websocket-vue3,我看官方文档和案例,没看到怎么连接多个的,所以放弃了,socket.io-client也试过了,是需要后端要下载socket.io?放弃了,最后实现如下要求:
- vue3+pinia实现封装websocket
- 单页面可调用多个websocke连接并互不影响
- 设置重连机制,并设置最大重连数
1.效果
1.1设置断线重连(设置最大重连数为5),效果如下
1.2发送消息
1.3连接多个
2.完整代码
2.1封装websocke
// stores/websocketStore.jsimport { 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.defaultReconnectAttempts const reconnectInterval = options.reconnectInterval ?? this.defaultReconnectInterval const 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) return if (connection.reconnectCount { if (connection.instance) { connection.instance.close() connection.instance = null } // 重新创建WebSocket实例而不重置计数器 this.createWebSocket(key, connection) }, connection.reconnectInterval) } else { // 最大重连尝试次数 reached console.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\";// // 获取storeconst 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!\");};
文章到此结束,希望对你有所帮助~