WebSocket

1.什么是webSocket

webSocket协议是HTML5的一种通信协议,该协议兼容我们常用的浏览器。例如Chrome、Firefox、IE等。它可以使客户端和服务端双向数据传输更加简单快捷,并且在TCP连接进行一次握手后,就可以持久性连接,同时允许服务端对客户端推送数据。外加传统模式的协议一般HTTP请求可能会包含较长的头部,但真正有效的可能只有小部分,从而占用了很多资源和带宽。因此WebSocket协议不仅实时通讯,支持扩展;也可以压缩节省服务器资源和带宽。WS协议和WSS协议两个均是WebSocket协议的SCHEM,两者一个是非安全的,一个是安全的。也是统一的资源标识符。其中WSS表示TLS之上的WebSocket。WS一般默认是80端口,而WSS默认是443端口。

2.vue如何实现webSocket

首先每次连接都会对应一个连接ID,这里我称为connectId,编写一个随机id生成函数

function getRandomNumber(){
    this.connectId = Math.floor(Math.random()*1000)
    //如果两台客户端使用了相同的connectId,发送消息时只会有一台收到,所以要询问后台id是否已经存在连接
    postAction(this.url.queryCId,{connectId:this.connectId}).then(res => {
        if(res.success && res.result===0){
            this.openSocket()
        }else{
            this.getRandomNumber()
        }
    })
}

接着我们建立一个websocket连接

function openSocket(){
    if(typrof WebSocket == 'undefined'){
    	console.log('您的浏览器不支持WebSocket')
	}else{
    	console.log('您的浏览器支持WebSocket')
    	let socketUrl = process.env.VUE_APP_BASEURL + this.connectId
        socketUrl = socketUrl.replace('https','ws').repalce('http','ws')
        if(this.socket != null){
            this.socket.close()
            this.socket = null
        }
        this.socket = new WebSocket(socketUrl)
        //打开事件
        this.socket.onopen = function(){
            console.log('websocket已经打开')
        }
        //获得消息
        this.socket.onmessage = function(msg){
            //对返回数据进行处理
        }
        //关闭事件
        this.socket.onclose = function(){
            console.log('websocket已关闭')
        }
        //发生了错误事件
        this.socket.onerror = function(e){
            console,log('websocket发生了错误')
            console.log(e)
        }
	}
}

在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件。这样可能会发生服务器会继续向客户端发送数据,并且这些数据会丢失。所以需要一种机制来检测客户端和服务端是否处于正常的链接状态。因此就有了websocket的心跳,检测链接的状态。

let lockReconnect = false; //避免重复连接
const heartCheck = {
    timeout:3000,
    timeoutobj:null,
    serverTimeoutObj:null,
    start:function(){
        let that = this
        clearTimeout(this.timeoutObj)
        clearTimeout(this.serverTimeoutObj)
        this.timeObj = setTimeout(function(){
            //这里发送一个心跳,后端收到后,返回一个心跳,这里用的ping-pong
            window.socket.send('ping')
            that.serverTimeoutObj = setTimeout(function(){
                window.socket.close()
            },that.timeout)
        },this.timeout)
    }
}
function createWebSocket(){
    try{
       let socketUrl = process.env.VUE_APP_BASEURL + this.connectId
		socketUrl = socketUrl.replace('https','ws').repalce('http','ws')
        this.socket = new WebSocket(socketUrl)
        init(socketUrl)
    }catch(e){
        console.log('catch');
        reconnect(socketUrl)
    }
}
function init(socketUrl){
    //打开事件
    this.socket.onopen = function(){
        console.log('websocket已经打开')
        //心跳检测重置
        heartCheck.start()
    }
    //获得消息
    this.socket.onmessage = function(msg){
        //对返回数据进行处理
        console.log(msg)
        heartCheck.start()
    }
    //关闭事件
    this.socket.onclose = function(){
        console.log('websocket已关闭')
        reconnect(socketUrl)
    }
    //发生了错误事件
    this.socket.onerror = function(e){
        console,log('websocket发生了错误'+e)
        reconnect(socketUrl)
    }
}
function reconnect(){
    if(lockReconnect){
        return
    }
    lockReconnect = true
    //没连接上会一直重连,设置延迟避免请求过多
    setTimeout(function(){
        this.createWebSocket()
        this.lockReconnect = false
    },2000)
}
Logo

前往低代码交流专区

更多推荐