当前位置 主页 > 服务器问题 > Linux/apache问题 >

    vue 实现websocket发送消息并实时接收消息

    栏目:Linux/apache问题 时间:2019-12-10 22:44

    公司做了个数字货币行情的H5,需要用到websocket,刚好自己也不会,可以学习一下,美滋滋。

    项目结合vue脚手架和websocket来搭建,主要遇到了两个问题,一个是:断开重连机制要如何处理;另外一个是:如何在页面上随时的发送消息并实时接收返回的数据,断开重连后又如何重新发送消息,接收消息

    一、断开重连机制处理 (详细参考这里

    写一个重连的方法(重连方法中必须加一把锁,重连方法执行过程中不再执行重连动作,避免重复连接),然后在websocket的onclose和error中绑定重连方法,这样一般情况下,websocket断开或者链接出错就可以实现重连了。针对断网重连问题,就需要用心跳检测了(主要是利用websocket定时发送消息,当超过一定时间消息还未发送成功,浏览器的websocket会自动触发onclose方法,而此时onclose有绑定了重连函数,于是就触发websocket重新连接),项目这边暂时不考虑这个,所以没做心跳检测。

    主要代码:

    let socket = null;
    let lockReconnet = false; //避免重复连接
    const wsUrl = '自己的websocket接口';
    let createSocket = url=>{ //创建socket
     try{
     if('WebSocket' in window){
     socket = new WebSocket(url)
     }else if('MozWebSocket' in window){
     socket = new MozWebSocket(url)
     }
     initSocket()
     }catch(e){
     reconnet(url)
     }
    }
    let initSocket = ()=>{ //初始化websocket
     socket.onopen = ()=>{
     console.log('socket连接成功')
     //heartCheck.reset().start() //后端说暂时不需要做心跳检测
     
     }
     
     socket.onmessage = (ev)=>{
     console.log(ev,'连接正常')
     //heartCheck.reset().start() //后端说暂时不需要做心跳检测
     }
     
     socket.onerror = ()=>{
     console.log('websocket服务出错了---onerror');
     reconnet(wsUrl) 
     }
     
     socket.onclose = ()=>{
     console.log('websocket服务关闭了+++onclose');
     reconnet(wsUrl)
     }
    }
    let reconnet = url=>{ //重新连接websock函数
     if(lockReconnet)
     return false
     lockReconnet = true
     setTimeout(()=>{
     createSocket(url)
     lockReconnet = false
     },2000)
    }
    let heartCheck = { //心跳检测
     timeout: 60*1000,
     timeoutObj: null,
     serverTimeoutObj: null,
     reset(){
     clearTimeout(this.timeoutObj)
     clearTimeout(this.serverTimeoutObj)
     return this;
     },
     start(){
     let that = this;
     this.timeoutObj = setTimeout(()=>{
     //发送数据,如果onmessage能接收到数据,表示连接正常,然后在onmessage里面执行reset方法清除定时器
     socket.send('heart check')
     this.serverTimeoutObj = setTimeout(()=>{
     socket.close()
     },that.timeout)
     },this.timeout)
     }
    }

    二、在页面上随时发送消息并实时接收消息

    在上面代码的基础上增加一个发送数据的方法,该方法有两个参数,一个是需要发送的数据;另一个为接收和处理返回数据的回调函数,然后把这个方法暴露出去并挂载到Vue原型上,这样就可以在任意页面或者组件随时的发送消息,并接收消息了。具体代码:

    let sendMsg = (data,callback)=>{ //发送数据,接收处理数据
     if(socket.readyState===1){
     globalCallback = callback; //把接收处理回调函数保存到全局
     sendData = data; //把发送数据也保存到全局
     
     data = JSON.stringify(data);
     socket.send(data);
     }else{
     setTimeout(()=>{
     console.log(socket,'等待socket链接成功')
     sendMsg(data,callback)
     },1500)
     return false
     }
     socket.onmessage = ev=>{ //重新监听onmessage,并把数据传给回调函数
     callback && callback(ev)
     }
    }