一、前言
项目中遇到通知模块,用到websocket的需求,便整理了一下。
二、什么是websocket
简单介绍下websocket是html5中长连接的协议,通过websocket能够实现服务端向客户端主动推送相关内容。
三、websocket在vue中的应用
由于项目中通知模块是全局的,所以本例中通过eventBus来进行组件中的通信。
// rest url /ws/
import Vue from 'vue';
// import '../plugins';
const vm = new Vue();
// const buildConfig = require('./buildConfig/' + BUILD_ENV + '.config');
const wsUri = `${WS_SERVER}/ws`;
// const wsUri = `ws://ws.qa.huohua.cn/ws`;
window.websocket = undefined;
function conn() {
var data = JSON.parse(localStorage.getItem('user_info'));
if (!data) return;
window.websocket = new WebSocket(wsUri);
window.websocket.onopen = function(evt) {
onOpen(evt);
};
window.websocket.onclose = function(evt) {
onClose(evt);
};
window.websocket.onmessage = function(evt) {
onMessage(evt);
};
window.websocket.onerror = function(evt) {
onError(evt);
};
}
function onOpen(evt) {
// console.info(new Date() + ':建立链接');
// 发送用户信息
doSend('PING');
var data = JSON.parse(localStorage.getItem('user_info'));
var param = { api: 'bindUserHandler', userId: data.id };
doSend(JSON.stringify(param));
}
function onClose(evt) {
// console.info(new Date() + ':链接关闭');
}
function onMessage(evt) {
// console.info(new Date() + ':收到消息:' + evt.data);
window.websocket.lastHeartbeat = new Date().getTime();
var data = JSON.parse(evt.data);
if (data.code <= 1002) {
return;
}
// 存储本地
if (data.code) {
if (!localStorage.getItem(data.data.bizType)) {
localStorage.setItem(data.data.bizType, JSON.stringify([]));
}
var allData = JSON.parse(localStorage.getItem(data.data.bizType));
allData.push(data.data.msg);
localStorage.setItem(data.data.bizType, JSON.stringify(allData));
vm.$bus.$emit('ws_', allData);
}
}
function onError(evt) {
// console.info(new Date() + ':发送错误:' + evt.data);
}
function doSend(message) {
// console.info(new Date() + ':SEND: ' + message);
if (window.websocket) window.websocket.send(message);
}
function initWs() {
if (!wsUri) {
// console.error('websocket未定义');
return;
}
if (!localStorage.getItem('user')) {
// console.error('未登录');
}
conn();
}
function reconn() {
if (window.websocket && window.websocket.lastHeartbeat) {
if (new Date().getTime() - window.websocket.lastHeartbeat > 1000 * 30) {
// console.info(new Date() + '心跳超时重连');
initWs();
}
} else {
initWs();
}
}
// 初始化链接
initWs();
// 发送心跳 五秒一次心跳
setInterval(function() {
doSend('PING');
}, 5000);
// 心跳超时
window.setInterval(reconn, 5000);