websoket初体验

2,458 阅读2分钟

一 websoket心跳机制

  • websoket心跳机制,是为了检测浏览器与服务端连接是否正常而存在的机制,如果不存在心跳机制,当浏览器异常或断网状态,浏览器或服务端可能一直发送无用的消息,浪费资源.检测原理就是定时向服务端发送消息表明连接正常,如果接收到响应就表明连接依旧存在可正常使用.

二 代码逻辑

//运行环境判断(获取不同环境名称的方法 dev/test/pre/online 本地等)
let environment = judgementEnvironment();
//各环境soket地址
let socketUrls = {
    dev: 'ws://xxx.dev.xxxxxx.xxx:8282',
    test: 'ws://xxx.test.xxxxxx.xxx:8282',
    pre: 'wss://xxx.pre.xxxxxx.xxx:8282',
    online: 'wss://xxx.xxxxxx.xxx:8282',
    develoop: 'ws://xxx.dev.xxxxxx.xxx:8282'
};
//当前环境soket地址(根据当前环境的名称获取soket不同的地址)
let socketUrl = socketUrls[environment];
//保存事件对象
let soketMethods;
//保存websocket对象
let socket;
// reConnect函数节流标识符
let flag = true;
//心跳机制
let heart = {
    timeOut: 20000,
    timeObj: null,
    serverTimeObj: null,
    start: function () {
        let self = this;
        //清除延时器
        this.timeObj && clearTimeout(this.timeObj);
        this.serverTimeObj && clearTimeout(this.serverTimeObj);
        this.timeObj = setTimeout(function () {
            socket.send('ping');//发送消息,服务端返回信息,即表示连接良好,可以在socket的onmessage事件重置心跳机制函数
            //定义一个延时器等待服务器响应,若超时,则关闭连接,重新请求server建立socket连接
            self.serverTimeObj = setTimeout(function () {
                socket.close();
                reConnect(socketUrl);
            }, self.timeOut)
        }, this.timeOut)
    }
}
//建立websocket连接函数(传入各个事件绑定的方法 {socketOpen:fn,socketMessage:fn,socketError:fn,socketClose:fn,send_msg:'后端要接收的消息'})
function createWebsocket(methods) {
    if (!soketMethods) soketMethods = methods;
    try {
        socket = new WebSocket(socketUrl);
        socketInit(soketMethods);
    } catch (e) {
        //进行重连;
        reConnect();
    }
}
//对WebSocket各种事件进行监听(传入各个事件绑定的方法 {socketOpen:fn,socketMessage:fn,socketError:fn,socketClose:fn,send_msg:'后端要接收的消息'})
function socketInit(soketMethods) {
    socket.onopen = function () {
        //连接已经打开,重置心跳机制
        heart.start();
        socket.send(soketMethods.send_msg);
        soketMethods.hasOwnProperty('socketOpen') && soketMethods.socketOpen();
    }
    socket.onmessage = function (event) {
        //通过event.data获取server发送的信息
        //对数据进行操作
        soketMethods.hasOwnProperty('socketMessage') && soketMethods.socketMessage(event.data);
        //收到消息表示连接正常,所以重置心跳机制
        heart.start();
    }
    socket.onerror = function () {
        //报错+重连
        soketMethods.hasOwnProperty('socketError') && soketMethods.socketError('socket连接出错');
        reConnect();
    }
    socket.onclose = function (event) {
        reConnect();
        soketMethods.hasOwnProperty('socketClose') && soketMethods.socketClose('socket连接关闭');
    }
}



//重连函数
//因为重连函数会被socket事件频繁触发,所以通过函数节流限制重连请求发送
function reConnect() {
    if (!flag) {
        return;
    }
    flag = false;
    setTimeout(function () {
        createWebsocket();
        flag = true;
    }, 6000)
}

三 http/https与websocket的ws/wss的关系

  • 在http下使用的是new WebSocket('ws://xxx');但是在切换到HTTPS后这个链接部分浏览器报错,实际上按照标准来是有如下对应关系.
    http -> new WebSocket('ws://xxx')
    https -> new WebSocket('wss://xxx')
  • 也就是在https下应该使用wss协议做安全链接,且wss下不支持ip地址的写法,写成域名形式.