[ vue版本点击这里](WebSocket聊天模板.md) ```JavaScript export default { namespaced: true, state: { // 是否打开连接 isOpen: false, // websocket socket: null, // 心跳间隔 timeout: 10000, // 心跳事件 interval: null, // 重连次数 connectNum: 0, // ws token token: '', // 当前聊天场景 currentToUser: { id: 1, name: '', avatar: '', type: 's', // s=单聊, g群聊 }, // 当前列表历史 wsHistory: [ ], // 我的信息 wsUserInfo: { addr: "", avatar: "", driver: "", fd: 0, id: 0, ip: "", nickName: "未登录", token: "", }, // 消息回调 wsCallback: null }, mutations: { // 关闭连接 wsClose(state) { if (state.isOpen) { state.isOpen = false; state.socket.close(); } }, // 登录 wsLogin(state, jwt) { this.dispatch('chat/SendRaw', { call: 'login.token', data: { token: jwt } }); }, // message 回调 set_message_callback(state, callback) { state.wsCallback = callback } }, actions: { initWs({ commit, state, rootState }) { console.log('检查是否已链接') if (state.isOpen) return; // 防止重复连接 //检查网络是否可用 const that = this; uni.getNetworkType({ success(result) { console.log('网络类型', result) if (result.networkType != 'none') { // 连接 console.log('开始ws链接') state.socket = uni.connectSocket({ url: rootState.wsUrl, complete: (e) => { console.log(e); }, }); if (!state.socket) return; // 监听开启 state.socket.onOpen(() => { console.log('ws连接成功') // 将连接状态设为已连接 state.isOpen = true; state.timer = null; //开启心跳 state.interval = setInterval(() => { //发送心跳 uni.sendSocketMessage({ data: 'ping', fail: function (e) { console.log('心跳发送失败了 ...执行重连'); uni.showToast({ title: '正在尝试重新链接第' + (state.connectNum + 1) + '次', icon: "none", }); state.isOpen = false; //执行重连 that.dispatch('chat/reConnect'); }, }); }, state.timeout); }); // 监听信息 state.socket.onMessage((e) => { if (e.data === 'pong') return; const pack = JSON.parse(e.data); if (typeof pack !== 'object') return; switch (pack.call) { case 'login.uid': // 登录 state.token = pack.result.token; state.wsUserInfo = pack.result; break; case 'chat.recv': const music = uni.createInnerAudioContext(); music.src = 'static/san.mp3'; music.autoplay = true; music.play(); break; } if (state.wsCallback !== null) { state.wsCallback(pack) } }) // 监听关闭 state.socket.onClose(() => { state.isOpen = false; state.socket = false; //清除定时器 clearTimeout(state.interval); state.interval = null }); // 监听错误 state.socket.onError((e) => { state.isOpen = false; state.socket = false; }); } else { console.log('网络已断开'); uni.showModal({ title: '网络错误', content: '请重新打开网络', showCancel: false, }) } } }) }, reConnect({ commit, state }) { if (state.connectNum < 20) { state.timer = setTimeout(() => { this.dispatch('chat/initWs') }, 3000) state.connectNum += 1; } else if (state._connectNum < 50) { state.timer = setTimeout(() => { this.dispatch('chat/initWs') }, 10000) state.connectNum += 1; } else { state.timer = setTimeout(() => { this.dispatch('chat/initWs') }, 450000) state.connectNum += 1; } }, // 发送消息 SendMsg({ commit, state }, payload) { var data = { to: payload.to, origin: state.currentToUser.type, type: payload.type, msg: payload.msg }; this.dispatch('chat/SendRaw', { call: 'chat.send', data: data }) }, //发送体 SendRaw({ commit, state }, data) { console.log(data); const message = { call: data.call, body: data.data, token: state.token }; const msgText = JSON.stringify(message) if (state.socket) { state.socket.send({ data: msgText, success: (res) => { console.log('发送成功'); }, fail: (e) => { console.log('发送失败', e); that.dispatch('chat/reConnect'); } }) } } } } ```