websocket使用教程—实时接收消息、心跳检测、刷新页面重连

一、新建webSocket.js:

import { Message } from 'element-ui';
import router from '../../router';

var lockReconnect = false; //避免ws重复连接
var isReconnect = true; //是否重连
var ws = null; // 判断当前浏览器是否支持WebSocket
var wsUrl = "路径";

function createWebSocket(wsUrl) {
    try {
        if ('WebSocket' in window) {
            ws = new WebSocket(wsUrl);
        } else if ('MozWebSocket' in window) {
            ws = new MozWebSocket(wsUrl);
        } else {
            Message('您的浏览器不支持websocket协议,建议使用新版谷歌、火狐等浏览器,请勿使用IE10以下浏览器,360浏览器请使用极速模式,不要使用兼容模式!')
        }
        initEventHandle();
    } catch (e) {
        if (isReconnect) {
            reconnect(wsUrl);
        }
        console.log(e);
    }
}

function initEventHandle() {
    ws.onclose = function () {
        console.log("连接关闭!" + new Date().toLocaleTimeString());
        if (isReconnect) {
            reconnect(wsUrl);
        }
    };
    ws.onerror = function () {
        Message('网络连接错误,请重新登录!')
        websocketColse();//主动关闭连接
        router.push("/login");
        console.log("连接错误!" + new Date().toLocaleTimeString());
        if (isReconnect) {
            reconnect(wsUrl);
        }
    };
    ws.onopen = function () {
        heartCheck.reset().start(); //心跳检测重置
        if (localStorage.getItem("userInfor")) {
            sendSock("SHIOT|REG|" + JSON.parse(localStorage.getItem("userInfor")).UserId);
        }
        console.log("连接成功!" + new Date().toLocaleTimeString());
    };
    ws.onmessage = function (event) { //如果获取到消息,心跳检测重置
        heartCheck.reset().start(); //拿到任何消息都说明当前连接是正常的
        console.log("收到消息啦:" + event.data)
        var arr = event.data.split('|')
        if (arr[1] == 'NEWS01') {
            var dataArr = event.data.split('|')
            Message.success('新消息:  ' + dataArr[4])
        }
        var eventData = event.data;
        handMsg(eventData);
    };
}

// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
    ws.close();
}

//刷新页面后需要重连
if (window.performance.navigation.type == 1 && localStorage.getItem("userInfor")) {
    if (isReconnect) {
        reconnect(wsUrl);
    }
}

//重连
function reconnect(wsUrl) {
    if (lockReconnect) return;
    lockReconnect = true;
    setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多
        createWebSocket(wsUrl);
        lockReconnect = false;
    }, 2000);
}

//心跳检测
var heartCheck = {
    //timeout: 540000,        //9分钟发一次心跳
    timeout: 3600, //1分钟发一次心跳
    // timeout: 10800, //3分钟发一次心跳
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function () {
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
        return this;
    },
    start: function () {
        var self = this;
        this.timeoutObj = setTimeout(function () {
            self.serverTimeoutObj = setTimeout(function () {
                //如果超过一定时间还没重置,说明后端主动断开了
                //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                // ws.close();
            }, self.timeout)
        }, this.timeout)
    }
}

// 实际调用的方法
function sendSock(agentData, callback) {
    // global_callback = callback;
    if (ws.readyState === ws.OPEN) {
        //若是ws开启状态
        websocketsend(agentData)
    } else if (ws.readyState === ws.CONNECTING) {
        // 若是 正在开启状态,则等待1s后重新调用
        setTimeout(function () {
            sendSock(agentData, callback);
        }, 1000);
    } else {
        // 若未开启 ,则等待1s后重新调用
        setTimeout(function () {
            sendSock(agentData, callback);
        }, 1000);
    }
}

//数据发送
function websocketsend(agentData) {
    ws.send(agentData);
}

//主动关闭连接
function websocketColse() {
    console.log("主动关闭连接!");
    isReconnect = false
    ws.close()
    ws = null
    lockReconnect = false
    localStorage.clear();
}

//处理消息
function handMsg(evtdata) {}


export default {
    sendSock,
    websocketColse,
    createWebSocket
}

二、main.js:

import socketApi from './components/common/webSocket';

Vue.prototype.$socketApi = socketApi;

三、在页面中使用:

this.$socketApi.websocketColse();

this.$socketApi.sendSock('发送指令');

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值