Browse Source

feat: ws storage

develop
wally 4 years ago
parent
commit
21b3a06b51
  1. 1
      CHANGELOG.md
  2. 8
      README.md
  3. 4
      src/store/index.js
  4. 3
      src/store/messages/getters.js
  5. 4
      src/store/messages/index.js
  6. 84
      src/store/messages/mutations.js
  7. 8
      src/store/messages/state.js
  8. 147
      src/store/socket/actions.js
  9. 5
      src/store/socket/index.js
  10. 26
      src/store/socket/mutations.js
  11. 7
      src/store/socket/state.js
  12. 100
      src/utils/storage.js
  13. 2
      src/utils/tall.js

1
CHANGELOG.md

@ -79,6 +79,7 @@
--|--|--
- | api 封装 | [8dcb8a2](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/8dcb8a2)
- | env host修改 | [a79a4a5](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/a79a4a5)
- | merge globals | [b0957cc](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/b0957cc)
- | mock | [51c24a5](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/51c24a5)
pwa 小程序 | 移除了pwa,alloyFinger添加平台判断 | [875fab4](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/875fab4)
- | uview-ui | [a9ea34b](http://gitea@dd.tall.wiki:wally/TALL-MUI-3/commits/a9ea34b)

8
README.md

@ -13,6 +13,14 @@ yarn
yarn dev:h5
```
浏览器输入网址:
127.0.0.1:8080/#/?u=xxx&p=x&r=x&pn=x
- u: userId
- p: projectId
- r: roleId
- pn: projectName
- t: taskId
+ 微信小程序
```
yarn dev:mp-weixin

4
src/store/index.js

@ -3,6 +3,8 @@ import Vuex from 'vuex';
import home from './home/index';
import db from './db/index';
import user from './user/index';
import messages from './messages/index';
import socket from './socket/index';
Vue.use(Vuex);
export default new Vuex.Store({ modules: { home, db, user } });
export default new Vuex.Store({ modules: { home, db, user, messages, socket } });

3
src/store/messages/getters.js

@ -0,0 +1,3 @@
const getters = {};
export default getters;

4
src/store/messages/index.js

@ -0,0 +1,4 @@
import state from './state';
import mutations from './mutations';
export default { namespaced: true, state, mutations };

84
src/store/messages/mutations.js

@ -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;

8
src/store/messages/state.js

@ -0,0 +1,8 @@
const state = {
syncMessages: [], // 同步消息
faultMessages: [], // 新收到的未处理的 故障消息
faults: [], // 所有的故障消息
game: [], // 游戏的消息
};
export default state;

147
src/store/socket/actions.js

@ -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;

5
src/store/socket/index.js

@ -0,0 +1,5 @@
import state from './state';
import mutations from './mutations';
import actions from './actions';
export default { namespaced: true, state, mutations, actions };

26
src/store/socket/mutations.js

@ -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;

7
src/store/socket/state.js

@ -0,0 +1,7 @@
const state = {
socket: null, // websocket实例
connected: false, // 是否处于连接状态
lockSocket: false, // 是否正在连接状态
};
export default state;

100
src/utils/storage.js

@ -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();
},
};

2
src/utils/tall.js

@ -1,11 +1,13 @@
import app from '@/config/app.js';
import zIndex from '@/config/zIndex.js';
import plugin from '@/config/plugin.js';
import storage from '@/utils/storage.js';
const $t = {
zIndex, // 定位元素层级
app, // app级别的相关配置
plugin, // 插件相关配置信息
storage, // 本地存储storage封装
};
uni.$t = $t;

Loading…
Cancel
Save