13 changed files with 404 additions and 2 deletions
@ -0,0 +1,3 @@ |
|||
const getters = {}; |
|||
|
|||
export default getters; |
@ -0,0 +1,4 @@ |
|||
import state from './state'; |
|||
import mutations from './mutations'; |
|||
|
|||
export default { namespaced: true, state, mutations }; |
@ -0,0 +1,84 @@ |
|||
import { setStorageSync, getStorageSync, removeStorageSync } from '@/utils/storage'; |
|||
|
|||
const mutations = { |
|||
/** |
|||
* 初始化消息栈 |
|||
* @param {object} state |
|||
* @param {string} type |
|||
* type: |
|||
* syncMessages 同步消息栈 |
|||
* faultMessages 故障消息 未处理消息栈 |
|||
* faults 所有的故障消息栈 |
|||
*/ |
|||
messagesInit(state, type) { |
|||
const messages = getStorageSync(type) ? JSON.parse(getStorageSync(type)) : []; |
|||
state[type] = messages; |
|||
}, |
|||
|
|||
/** |
|||
* 将新 消息添加到 消息栈 最前边 |
|||
* @param { object } state |
|||
* @param { object } data |
|||
* data: message, type |
|||
* message 消息对象 |
|||
* type: |
|||
* syncMessages 同步消息栈 |
|||
* faultMessages 故障消息 未处理消息栈 |
|||
* faults 所有的故障消息栈 |
|||
* game 游戏的消息 |
|||
* |
|||
* cache: boolean true 本地存储 false 不存储 |
|||
*/ |
|||
messagesAdd(state, data) { |
|||
const messages = state[data.type]; |
|||
if (messages.length > 0) { |
|||
const result = messages.find(msg => msg.id === data.message.id); |
|||
if (result) return; |
|||
} |
|||
messages.unshift(data.message); |
|||
// eslint-disable-next-line no-param-reassign
|
|||
state[data.type] = messages; |
|||
if (data.cache) { |
|||
setStorageSync(data.type, JSON.stringify(messages)); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 通过消息id移除指定 同步 消息 |
|||
* @param { object } state |
|||
* @param { object } data |
|||
* data: messageId, type |
|||
* messageId: 要移除的消息的messageId |
|||
* type: |
|||
* syncMessages 同步消息栈 |
|||
* faultMessages 故障消息 未处理消息栈 |
|||
* faults 所有的故障消息栈 |
|||
* cache: boolean true 本地存储 false 不存储 |
|||
*/ |
|||
messagesRemoveById(state, data) { |
|||
const messages = state[data.type]; |
|||
const index = messages.findIndex(msg => msg.id === data.messageId); |
|||
if (index < 0) return; |
|||
messages.splice(index, 1); |
|||
// eslint-disable-next-line no-param-reassign
|
|||
state[data.type] = messages; |
|||
if (data.cache) { |
|||
setStorageSync(data.type, JSON.stringify(messages)); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* 清除指定type的消息 |
|||
* @param {any} state |
|||
* @param {object} data |
|||
* data: type, cache |
|||
*/ |
|||
messagesClear(state, data) { |
|||
state[data.type] = []; |
|||
if (data.cache) { |
|||
removeStorageSync(data.type); |
|||
} |
|||
}, |
|||
}; |
|||
|
|||
export default mutations; |
@ -0,0 +1,8 @@ |
|||
const state = { |
|||
syncMessages: [], // 同步消息
|
|||
faultMessages: [], // 新收到的未处理的 故障消息
|
|||
faults: [], // 所有的故障消息
|
|||
game: [], // 游戏的消息
|
|||
}; |
|||
|
|||
export default state; |
@ -0,0 +1,147 @@ |
|||
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 }) { |
|||
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 '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; |
@ -0,0 +1,5 @@ |
|||
import state from './state'; |
|||
import mutations from './mutations'; |
|||
import actions from './actions'; |
|||
|
|||
export default { namespaced: true, state, mutations, actions }; |
@ -0,0 +1,26 @@ |
|||
const mutations = { |
|||
// 设置socket实例
|
|||
setSocket(state, socket) { |
|||
state.socket = socket; |
|||
}, |
|||
|
|||
/** |
|||
* 设置socket连接状态 |
|||
* @param {Object} state |
|||
* @param {boolean} connected 是否连接 true -> 连接 |
|||
*/ |
|||
setConnected(state, connected) { |
|||
state.connected = connected; |
|||
}, |
|||
|
|||
/** |
|||
* 设置连接锁 正在连接中 锁上 避免多个连接同时发出 |
|||
* @param {Object} state |
|||
* @param {boolean} lockSocket 是否正在连接的过程中 |
|||
*/ |
|||
setLockSocket(state, lockSocket) { |
|||
state.lockSocket = lockSocket; |
|||
}, |
|||
}; |
|||
|
|||
export default mutations; |
@ -0,0 +1,7 @@ |
|||
const state = { |
|||
socket: null, // websocket实例
|
|||
connected: false, // 是否处于连接状态
|
|||
lockSocket: false, // 是否正在连接状态
|
|||
}; |
|||
|
|||
export default state; |
@ -0,0 +1,100 @@ |
|||
export default { |
|||
/** |
|||
* 设置本地存储 同步 |
|||
* @param {string} key |
|||
* @param {*} data |
|||
*/ |
|||
setStorageSync(key, data) { |
|||
const value = typeof data === 'string' ? data : JSON.stringify(data); |
|||
uni.setStorageSync(key, value); |
|||
}, |
|||
|
|||
/** |
|||
* 获取本地存储的信息 根据key |
|||
* @param {string} key |
|||
* @return {string} |
|||
*/ |
|||
getStorageSync(key) { |
|||
return uni.getStorageSync(key); |
|||
}, |
|||
|
|||
/** |
|||
* 根据key移除某条数据 同步 |
|||
* @param {string} key |
|||
*/ |
|||
removeStorageSync(key) { |
|||
uni.removeStorageSync(key); |
|||
}, |
|||
|
|||
/** |
|||
* 清楚全部数据 同步 |
|||
*/ |
|||
clearStorageSync() { |
|||
uni.clearStorageSync(); |
|||
}, |
|||
|
|||
/** |
|||
* 设置本地存储 异步 |
|||
* @param {string} key |
|||
* @param {*} data |
|||
*/ |
|||
setStorage(key, data) { |
|||
return new Promise((resolve, reject) => { |
|||
const value = typeof data === 'string' ? data : JSON.stringify(data); |
|||
uni.setStorage({ |
|||
key, |
|||
data: value, |
|||
success() { |
|||
resolve(`数据${key}存储成功`); |
|||
}, |
|||
fail() { |
|||
reject(`数据${key}存储失败`); |
|||
}, |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 获取本地存储的信息 根据key 异步 |
|||
* @param {string} key |
|||
* @return {string} |
|||
*/ |
|||
getStorage(key) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.getStorage({ |
|||
key, |
|||
success(res) { |
|||
resolve(res.data); |
|||
}, |
|||
fail(error) { |
|||
reject(`数据${key}获取失败, error: ${error}`); |
|||
}, |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 根据key移除某条数据 异步 |
|||
* @param {string} key |
|||
*/ |
|||
removeStorage(key) { |
|||
return new Promise((resolve, reject) => { |
|||
uni.removeStorage({ |
|||
key, |
|||
success(res) { |
|||
resolve(res); |
|||
}, |
|||
fail(error) { |
|||
reject(`数据${key}删除失败, error: ${error}`); |
|||
}, |
|||
}); |
|||
}); |
|||
}, |
|||
|
|||
/** |
|||
* 清楚全部数据 异步 |
|||
*/ |
|||
clearStorage() { |
|||
uni.clearStorage(); |
|||
}, |
|||
}; |
Loading…
Reference in new issue