websocket 在Vue中应用

1,357 阅读1分钟

一、前言

项目中遇到通知模块,用到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);