import Config from "@/common/js/config.js" let prevSendTimeMs = 0; // 上一条消息发送时间 let socketMsgQueue = []; // socket消息队列 let sendHeartTimer = null; let heartbeatConst = 15000; // 心跳常量 const actions = { // 初始化socket initSocket({ commit, dispatch, state }) { if (state.lockSocket) return; // const { token } = rootState.user; // if (!token) return; commit('setLockSocket', true); commit('setSocket', uni.connectSocket({ url: Config.msgUrl, complete: () => {} })); // dispatch('auth'); dispatch('onSocketOpen'); dispatch('onSocketMessage'); dispatch('onSocketClose'); state.socket.onError(errMsg => console.error(errMsg)); commit('setLockSocket', false); }, // websocket发送channelId进行认证 auth({ dispatch }) { const token = uni.$storage.getStorageSync('anyringToken'); const data = { type: 'Auth', data: { token } }; dispatch('sendSocketMessage', data); }, // 监听ws打开 onSocketOpen({ dispatch, commit, state }) { state.socket.onOpen(res => { commit('setConnected', true); prevSendTimeMs = Date.now(); dispatch('auth'); // 认证 // for (let i = 0; i < socketMsgQueue.length; i++) { // dispatch('sendSocketMessage', socketMsgQueue[i]); // } // socketMsgQueue = []; }); }, // 监听收到的ws消息 onSocketMessage({ commit, dispatch, state }) { state.socket.onMessage(res => { 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, state }, item) { const data = JSON.parse(item.data); switch (data.type) { case 'ChannelStatus': // 认证 dispatch('handleAuthMessage', data); break; case 'Notification': // 系统通知 commit('setNotificationData', item); break; case 'Ring': // ring commit('setRingData', item); break; case 'Remind': // 小红点 commit('setRemindData', item); break; case 'SetMsgSuccess': // 成功 let arr = []; if (data.event === 'Notification') { arr = state.notificationData; } else if (data.event === 'Ring') { arr = state.ringData; } else if (data.event === 'Remind') { arr = state.remindData; } let del_index = -1; arr.forEach((item, index) => { if (item.id === data.data.msgId) { del_index = index; } }) arr.splice(del_index, 1); if (data.event === 'Notification') { commit('uploadNotificationData', arr); } else if (data.event === 'Ring') { commit('uploadRingData', arr); } else if (data.event === 'Remind') { commit('uploadRemindData', arr); } break; default: break; } }, // 发送消息 sendSocketMessage({ state }, data) { if (state.connected) { prevSendTimeMs = Date.now(); const msg = JSON.stringify({ toDomain: 'Server', data: JSON.stringify(data) }); state.socket.send({ data: msg }); } else { socketMsgQueue.push(data); } }, // 监听关闭事件 onSocketClose({ dispatch, commit, state }) { state.socket.onClose(() => { commit('setConnected', false); if (sendHeartTimer) clearInterval(sendHeartTimer); setTimeout(() => { dispatch('initSocket'); }, 300); }); }, /** * 处理auth认证返回的ChannelStatus消息 * @param {object} data 消息内容对象 */ handleAuthMessage({ commit, dispatch }, data) { if (data.data.authed) { dispatch('sendHeart'); } else { uni.$u.toast(data.data.error.text); uni.$storage.removeStorageSync('anyringToken'); commit('setSocket', null); } }, // 心跳检测 sendHeart({ dispatch, state }) { if (sendHeartTimer) clearInterval(sendHeartTimer); sendHeartTimer = setInterval(() => { if (Date.now() - prevSendTimeMs >= heartbeatConst) { dispatch('sendSocketMessage', { type: 'Ping' }); } }, 5000); }, }; export default actions;