uniapp websocket封装(多个websocket连接)
·
该文章针对需要进行多个websocket连接,并且全局连接与页面单独连接做区分,并且页面单独连接的websocket可以针对具体连接进行关闭的功能 。若只有单个websocket连接需求,则参考另一篇文章uniapp websocket的封装与使用_uniapp 小程序 webscket 封装-CSDN博客
一、新建websocket.js文件
在common目录下新建websocket.js文件
class WebsocketUtil {
constructor(url, time) {
this.is_open_socket = false // 避免重复连接
this.url = url // 地址
this.data = null
// 心跳检测
this.timeout = time // 多少秒执行检测
this.heartbeatInterval = null // 检测服务器端是否还活着
this.reconnectInterval = null // 重连之后多久再次重连
this.messageCallbacks = [] // 存储消息回调函数
this.store = null // 存储Vuex store引用
try {
return this.connectSocketInit()
} catch (e) {
this.is_open_socket = false
}
}
// 设置store
setStore(store) {
this.store = store
}
// 创建WebSocket连接
connectSocketInit() {
if (this.is_open_socket) return
this.socketTask = uni.connectSocket({
url: this.url,
success: () => {
this.is_open_socket = true
return this.socketTask
},
})
this.socketTask.onOpen((res) => {
clearInterval(this.reconnectInterval)
clearInterval(this.heartbeatInterval)
this.is_open_socket = true
this.start()
this.socketTask.onMessage((res) => {
try {
const data = JSON.parse(res.data)
// 如果有store,将数据存入store
if (this.store) {
this.store.commit('setWebSocketData', data)
}
// 执行所有注册的回调函数
this.messageCallbacks.forEach(callback => callback(data))
} catch (e) {
console.error('WebSocket消息解析错误:', e)
}
})
})
this.socketTask.onError((res) => {
this.is_open_socket = false
if (this.socketTask) {
this.socketTask.close()
}
})
this.socketTask.onClose(() => {
this.is_open_socket = false
})
}
// 发送消息
send(value) {
if (!this.is_open_socket) return
this.socketTask.send({
data: JSON.stringify(value),
success() {
console.log("消息发送成功", value)
},
fail(err) {
console.error("消息发送失败", err)
}
})
}
// 关闭连接
close() {
clearInterval(this.heartbeatInterval)
clearInterval(this.reconnectInterval)
this.is_open_socket = false
if (this.socketTask) {
this.socketTask.close()
}
}
// 开启心跳检测
start() {
// this.heartbeatInterval = setInterval(() => {
// const heartbeatMsg = {
// type: 'heartbeat',
// userId: uni.getStorageSync('userinfo')?.user_id
// }
// this.send(heartbeatMsg)
// }, this.timeout)
}
// 重新连接
reconnect() {
clearInterval(this.heartbeatInterval)
if (!this.is_open_socket) {
this.reconnectInterval = setInterval(() => {
this.connectSocketInit()
}, 3000)
}
}
// 注册消息回调
onMessage(callback) {
this.messageCallbacks.push(callback)
}
// 移除消息回调
offMessage(callback) {
this.messageCallbacks = this.messageCallbacks.filter(cb => cb !== callback)
}
}
class WebSocketManager {
constructor() {
this.connections = {}; // 存储所有WebSocket连接
this.globalConnections = []; // 存储需要全局管理的连接名称
}
// 创建全局连接
createGlobalConnection(name, url, time, store) {
if (!this.connections[name]) {
this.connections[name] = new WebsocketUtil(url, time);
if (store) this.connections[name].setStore(store);
this.globalConnections.push(name);
}
return this.connections[name];
}
// 创建页面级连接
createPageConnection(name, url, time) {
if (!this.connections[name]) {
this.connections[name] = new WebsocketUtil(url, time);
}
return this.connections[name];
}
// 获取连接
getConnection(name) {
return this.connections[name];
}
// 关闭指定连接
closeConnection(name) {
console.log('关闭指定连接', name)
if (this.connections[name]) {
this.connections[name].close();
delete this.connections[name];
// 从全局连接列表中移除
this.globalConnections = this.globalConnections.filter(n => n !== name);
}
}
// 关闭所有全局连接
closeAllGlobalConnections() {
this.globalConnections.forEach(name => {
this.closeConnection(name);
});
}
// 关闭所有连接
closeAllConnections() {
Object.keys(this.connections).forEach(name => {
this.connections[name].close();
});
this.connections = {};
this.globalConnections = [];
}
}
// 导出单例实例
export const webSocketManager = new WebSocketManager();
export default WebsocketUtil;
二、调用方法
1、在全局调用
在APP.vue中调用,按需调用,可调用多个不同链接的websocket,若只需调用一个,将ws2的删掉即可。注:store状态管理为接收到的websocket数据进行全局变量的设置,方便在其他页面进行调用
<script>
//App.vue
import {
webSocketManager
} from '@/common/websocket.js';
import store from './store/index.js'
export default {
onLaunch() {
// 初始化全局WebSocket连接
webSocketManager.createGlobalConnection(
'ws1',
'你的websocket链接',
30000,
store
);
webSocketManager.createGlobalConnection(
'ws2',
'你的websocket链接',
30000,
store
);
// 注册全局消息处理
webSocketManager.getConnection('ws1').onMessage((data) => {
console.log('ws1收到消息:', data);
// 处理消息逻辑
});
webSocketManager.getConnection('ws2').onMessage((data) => {
console.log('ws2收到消息:', data);
// 处理消息逻辑
});
},
onShow() {
// 检查并重连全局连接
this.reconnectGlobalSockets();
},
onHide() {
// 小程序进入后台时的处理
},
onUnload() {
// 关闭所有全局连接
webSocketManager.closeAllGlobalConnections();
},
methods: {
reconnectGlobalSockets() {
const globalConnections = ['ws1'];
globalConnections.forEach(name => {
const conn = webSocketManager.getConnection(name);
if (!conn || !conn.is_open_socket) {
webSocketManager.createGlobalConnection(
name,
conn ? conn.url : `wss://your-domain.com/${name}`,
30000,
store
);
}
});
}
}
}
</script>
<style>
/*每个页面公共css */
</style>
2、在单个页面调用
<template>
<view class="content">
<text>详情页</text>
</view>
</template>
<script>
import {
webSocketManager
} from '@/common/websocket.js';
export default {
data() {
return {
detailSocket: null
}
},
onLoad() {
// 创建详情页专用的WebSocket连接
this.detailSocket = webSocketManager.createPageConnection(
'detailWs',
'你的websocket链接',
30000
);
// 注册消息回调
this.detailSocket.onMessage((data) => {
console.log('详情页收到消息:', data);
// 处理消息逻辑
});
},
onUnload() {
if (this.detailSocket) {
// 先移除所有消息回调
this.detailSocket.messageCallbacks = this.detailSocket.messageCallbacks.filter(
cb => cb !== this.handleDetailMessage
);
// 如果是独立连接才关闭
if (webSocketManager.getConnection('detailWs')) {
webSocketManager.closeConnection('detailWs');
}
this.detailSocket = null;
}
},
methods: {
sendDetailMessage(data) {
if (this.detailSocket && this.detailSocket.is_open_socket) {
this.detailSocket.send(data);
} else {
console.error('WebSocket连接未就绪');
}
},
messageHandler(data) {
// 专门处理详情页消息
}
}
}
</script>
<style>
</style>
3、关闭单个页面中指定websocket连接
webSocketManager.closeConnection('detailWs');
三、store状态管理
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
websocketData: null,
},
mutations: {
setWebSocketData(state, data) {
state.websocketData = data
}
},
getters: {
getWebSocketData: state => state.websocketData,
}
})
export default store
//main.js
import App from './App'
import store from './store/index.js'
const app = new Vue({
store,
...App
})
四、在页面中拿到websocket接收到数据
<script>
import {
mapState,
} from 'vuex'
export default {
data() {
return {
}
},
computed: {
...mapState(['websocketData'])
},
watch:{
websocketData(newval,oldval){
//监听数据变化
console.log('WebSocket 数据变化:', newval)
}
},
}
</script>
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)