const WS_BASE_URL = process.env.VUE_APP_MSG_URL; let prevTime = 0; let socketMsgQueue = []; // socket消息队列 let sendHeartTimer = null; const actions = { // 初始化socket initSocket({ commit, dispatch, state, rootState }) { if (state.lockSocket) return; const { token } = rootState.user; if (!token) return; commit('setLockSocket', true); commit('setSocket', uni.connectSocket({ url: WS_BASE_URL, complete: () => {} })); dispatch('onSocketOpen'); dispatch('onSocketMessage'); dispatch('onSocketClose'); state.socket.onError(errMsg => console.error(errMsg)); commit('setLockSocket', false); }, // 监听ws打开 onSocketOpen({ dispatch, commit, state }) { // eslint-disable-next-line no-unused-vars state.socket.onOpen(res => { // console.log('ws open: ', res); commit('setConnected', true); prevTime = Date.now(); // this.auth(); dispatch('auth'); for (let i = 0; i < socketMsgQueue.length; i++) { dispatch('sendSocketMessage', socketMsgQueue[i]); } socketMsgQueue = []; }); }, // 监听收到的ws消息 onSocketMessage({ dispatch, state }) { state.socket.onMessage(res => { // console.log('收到消息:', res); prevTime = Date.now(); if (!res || !res.data || !JSON.parse(res.data)) return; const resData = JSON.parse(res.data); const { messageSet, ackId } = resData; // 处理消息体对象 messageSet.forEach(item => dispatch('handleMessagesData', item)); ackId && dispatch('sendSocketMessage', { type: 'Ack', data: { ackId } }); }); }, /** * 处理收到的消息内容 * @param {object} item 单个消息体对象 */ handleMessagesData({ dispatch, commit }, item) { const data = JSON.parse(item.data); switch (data.type) { case 'Sync': // 开始某个节点 commit('messages/messagesAdd', { message: data, type: 'syncMessages' }, { root: true }); break; case 'taskStatus': // 任务状态修改相关消息 commit('task/setTaskStatus', data.data, { root: true }); break; // case 'Chrome': // !收到开始游戏的消息 // console.log('handleMessagesData', data); // // @ts-ignore // util.openGameApp({ // type: data.data.type, // projectId: data.data.projectId, // id: data.data.recordId, // token: rootState.user.token, // }); // break; // case 'Deliver': // 交付物相关消息 // commit('messages/messagesAdd', { type: 'checkMessages', message: data }, { root: true }); // break; case 'ChannelStatus': dispatch('handleAuthMessage', data); break; // case 'switchoverProject': // 康复相关消息 // dispatch('home/getProjectById', data.data.projectId, { root: true }); // break; // case 'startDrill': // 康复开始训练相关消息 // console.log('setStartDrillInfo', data.data); // commit('home/setStartDrillMessages', data.data, { root: true }); // break; default: break; } }, // 发送消息 sendSocketMessage({ state }, data) { if (state.connected) { const msg = JSON.stringify({ toDomain: 'Server', data: JSON.stringify(data) }); state.socket.send({ data: msg }); } else { socketMsgQueue.push(data); } }, // 监听关闭事件 onSocketClose({ dispatch, commit, state }) { // console.log('onSocketClose'); state.socket.onClose(() => { commit('setConnected', false); if (sendHeartTimer) clearInterval(sendHeartTimer); setTimeout(() => { dispatch('initSocket'); }, 300); }); }, // websocket发送channelId进行认证 auth({ dispatch, rootState }) { const { token } = rootState.user; if (!token) return; const data = { type: 'Auth', data: { token } }; dispatch('sendSocketMessage', data); }, // 心跳检测 sendHeart({ dispatch, state }) { if (sendHeartTimer) clearInterval(sendHeartTimer); sendHeartTimer = setInterval(() => { if (Date.now() - prevTime >= 15000) { dispatch('sendSocketMessage', { type: 'Ping' }); if (Date.now() - prevTime >= 20000) { state.socket.close(); } } }, 5000); }, /** * 处理auth认证返回的ChannelStatus消息 * @param {object} data 消息内容对象 */ handleAuthMessage({ commit, dispatch }, data) { if (data.data.authed) { dispatch('sendHeart'); } else { uni.$u.toast('消息系统认证失败, 请退出重新登录'); uni.$t.removeStorageSync('anyringToken'); commit('setSocket', null); } }, }; export default actions;