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.
 
 
 
 
 

245 lines
7.2 KiB

import { WS_BASE_URL } from 'config/api';
import { mapGetters, mapMutations } from 'vuex';
let connected = false; // socket 是否连接
let socket = null; // websocket 实例
let lockSocket = false;
let socketMsgQueue = []; // socket消息队列
let prevTimestamp = 0; // 上次收到消息的时间戳
let sendHeartTimer = null; // 💓的timer计时器
const mixin = {
// computed: mapGetters('home', ['projectId']),
mounted() {
socket ? socket.close() : this.initSocket();
},
methods: {
...mapMutations('messages', [
'messagesAdd',
'messagesAddWeight',
'setStartMessages',
'messagesAddRfid',
'messagesAddWeighSensor1',
'messagesAddWeighSensor2',
'messagesAddWeighSensor3',
'messagesAddWeighSensor4',
'messagesAddVibrationSensor',
'messagesAddThrombolyticDose',
'messagesAddBolusDose',
'messagesAddMaintenanceDose',
]),
// ...mapMutations('home', ['increaseProjectsRingNum']),
// 初始化websocket
initSocket() {
if (lockSocket) return;
console.log('初始化websocket');
lockSocket = true;
// const token = sessionStorage.getItem('anyringToken');
// if (!token) return;
if ('WebSocket' in window) {
socket = new WebSocket(WS_BASE_URL);
socket.onopen = this.websocketOpen;
socket.onmessage = this.websocketOnMessage;
socket.onclose = this.websocketClose;
socket.onerror = this.websocketError;
} else {
// @ts-ignore
this.$message.error('当前浏览器不支持 websocket');
}
lockSocket = false;
},
/**
* 处理收到的消息内容
* @param {object} item 单个消息体对象
*/
handleMessagesData(item) {
const data = JSON.parse(item.data);
switch (data.type) {
case 'ChannelStatus': // 认证消息
this.handleAuthMessage(data);
break;
case 'CarRecord': // 平车
// if (!data.data.type) return;
switch (data.data.type) {
case 0: // 开始
// 收到开始消息
this.setStartMessages(true);
this.messagesAddRfid(null);
break;
case 1: // 体重
// 收到同步消息
// 把消息添加到store 的消息栈中
this.messagesAddWeight(data.data.value);
break;
case 2: // RFID
this.messagesAddRfid(data.data);
break;
case 3: // 称重传感器一
this.messagesAddWeighSensor1(data.data.value);
break;
case 4: // 称重传感器二
this.messagesAddWeighSensor2(data.data.value);
break;
case 5: // 称重传感器三
this.messagesAddWeighSensor3(data.data.value);
break;
case 6: // 称重传感器四
this.messagesAddWeighSensor4(data.data.value);
break;
case 7: // 震动传感器
this.messagesAddVibrationSensor(data.data);
break;
case 8: // 溶栓剂量(总量)
this.messagesAddThrombolyticDose(data.data.value);
break;
case 9: // 团注剂量
this.messagesAddBolusDose(data.data.value);
break;
case 10: // 维持剂量
this.messagesAddMaintenanceDose(data.data.value);
break;
default:
break;
}
break;
default:
break;
}
},
/**
*
* data:{
* data: {
* value: ''
* },
* type: '',
* }
*/
/**
* 收到ws 消息
* @param {object} res 收到的消息数据
*/
async websocketOnMessage(res) {
try {
prevTimestamp = Date.now();
// console.warn('message: ', res, new Date().toLocaleString());
if (res && res.data && JSON.parse(res.data)) {
const resData = JSON.parse(res.data);
const { messageSet, ackId } = resData;
// 处理消息体对象
messageSet.forEach(item => this.handleMessagesData(item));
// console.log('ackId', ackId);
// 有ackId 发送ack
ackId && this.sendSocketMessage({ type: 'Ack', data: { ackId } });
}
} catch (error) {
console.error('error: ', error);
}
},
// 打开socket
websocketOpen() {
console.log('打开socket');
// console.warn('socket 打开成功', new Date().toLocaleString());
connected = true;
prevTimestamp = Date.now();
this.auth();
for (let i = 0; i < socketMsgQueue.length; i += 1) {
this.sendSocketMessage(socketMsgQueue[i]);
}
socketMsgQueue = [];
},
// 发送消息
sendSocketMessage(data) {
console.log('发送消息');
// console.warn('send:', data, new Date().toLocaleString());
if (connected) {
if (socket.readyState === 1) {
socket.send(JSON.stringify({ toDomain: 'Server', data: JSON.stringify(data) }));
}
} else {
socketMsgQueue.push(data);
}
},
// 关闭socket
websocketClose(e) {
console.log('关闭socket');
// console.warn(e);
connected = false;
if (sendHeartTimer) clearInterval(sendHeartTimer);
// console.warn('close:', connected, new Date().toLocaleString());
if (!e || e.code !== 1005) {
socket.close();
}
setTimeout(() => {
// connected 在这里的作用是:
// 在发生重连 但是还没连上之前 不要再次重连
this.initSocket();
}, 300);
},
// 连接失败
websocketError() {
console.log('连接失败');
console.warn('error = ', connected);
},
// websocket发送token进行认证
auth() {
console.log('进行认证');
// const token = sessionStorage.getItem('anyringToken');
// if (!token) return;
const query = this.$route.query;
const userId = query && query.userId ? query.userId : '1338747522436435968';
const data = { type: 'Auth', data: { userId }, major: 1, minor: 1 };
this.sendSocketMessage(data);
},
// 心跳检测
sendHeart() {
console.log('心跳检测');
if (sendHeartTimer) clearInterval(sendHeartTimer);
sendHeartTimer = setInterval(() => {
if (Date.now() - prevTimestamp >= 15000) {
this.sendSocketMessage({ type: 'Ping' });
if (Date.now() - prevTimestamp > 20000) {
// console.warn('手动断开');
socket.close();
}
}
}, 5000);
},
/**
* 处理auth认证返回的ChannelStatus消息
* @param {object} data 消息内容对象
*/
handleAuthMessage(data) {
console.log('认证信息');
if (data.data.authed) {
// 认证成功
this.sendHeart();
} else {
// this.$message.error('消息系统认证失败, 请重新登录');
// 清除掉本地无用的token
// sessionStorage.removeItem('anyringToken');
socket = null;
// setTimeout(() => {
// this.$router.push('/user/login');
// }, 1000);
}
},
},
};
export default mixin;