You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
4.7 KiB
161 lines
4.7 KiB
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 }) {
|
|
let timer = setInterval(() => {
|
|
const token = uni.$storage.getStorageSync('anyringToken');
|
|
if (token) {
|
|
const data = { type: 'Auth', data: { token } };
|
|
dispatch('sendSocketMessage', data);
|
|
clearInterval(timer);
|
|
}
|
|
}, 1000);
|
|
},
|
|
|
|
// 监听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;
|
|
}
|
|
})
|
|
|
|
if (del_index > -1) {
|
|
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;
|
|
|