Jason2zi 2022-08-23 17:12 采纳率: 61.5%
浏览 125
已结题

VUE调用Websocket对象报错

页面会有多个组件调用connectWs(),求分析报错的原因,有还需要了解可以留言,非常感谢。
Chrome报错:

img

火狐报错:

img

以下是public.js封装的方法


    Vue.prototype.connectWs = function (subscribeArr) {
      if (typeof (WebSocket) == undefined) return
      if (ws == null || ws.readyState != 1) {
        let profitOld = "--", rateProfitOld = "--";
        ws = new WebSocket(store.state.wsUrl)
        store.state.ws = ws;
        ws.onopen = (ddd) => {
          ws.send(wsLoginBag(this.$md5, subscribeArr));
          wsInterval = setInterval(() => {
            ws.send(JSON.stringify({command: 3}))
          }, 6000)
        }
        if (localStorage.newPriceKey) {
          newPrice = JSON.parse(localStorage.newPriceKey)
        }

        ws.onmessage = (e) => {
          let data = JSON.parse(e.data);
          let body = data.body
          if (data.command == 11) {
            ws.send(wsChangeDestine(subscribeArr));
            return
          }
          if (data.command == 12) { 
            if (body && body.length > 0) {
              body.forEach(item => {
               //...
                if (isNaN(parseFloat(profitOld))) {
                  profitOld = "--"
                }
                if (isNaN(parseFloat(rateProfitOld))) {
                  rateProfitOld = "--"
                }
                newPrice[item.symbol] = {
                  //...
                }
                this.resetSetItem("newPriceKey", JSON.stringify(newPrice))
              })
            }
          }

          if (data.command == 14) {
            if (body.code == 0) return false;
            let sd = newPrice[body.symbol];
            if (!sd) return;
            if (sd.yesterdayClose != 0) {
              //...
              if (isNaN(parseFloat(profitOld))) {
                profitOld = "--"
              }
              if (isNaN(parseFloat(rateProfitOld))) {
                rateProfitOld = "--"
              }
            }
            //...
            this.resetSetItem("newPriceKey", JSON.stringify(newPrice))
          }
        }
        ws.onerror = (err) => {
          clearInterval(this.wsInterval)
        }
        ws.onclose = (err) => {
          clearInterval(this.wsInterval)
        }
      } else if(ws != null && ws.readyState == 1)  {
        ws.send(wsChangeDestine(subscribeArr));
      }
    }
  • 写回答

8条回答 默认 最新

  • ilmss 2022-08-23 17:23
    关注

    你需要监听WebSocket是否处于关闭状态的判断吧

    
    var socket = new WebSocket("localhost:8080/websocket");
    if(socket.readyState != socket.OPEN){
        alert("连接已中断!")
        
        //todo...
     
        return false;
    

    另外,你的服务端是否收到客户端的心跳?
    连接加个定时器:

    var interval_timer = null;//计时器
    var timer_count = 0;
    
    var ws =  new WebSocket("wss://eee.com/ssssmn");
        ws.onmessage = function (e) {
            var message = eval('(' + e.data + ')');
            switch (message.type) {
                case 'init':
                    changeNoReadLogs();
                    var bind = '{"type":"bind","from_id":"' + from_id + '","to_id":"' + to_id + '"}';
                    ws.send(bind);
                    message_load();
                    break;
                ....... 具体代码省略......
            }
        };
        ws.onclose = function (e) {
            console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean);
        };
        // 开启定时器
        init_start_timer();
        /**
         * 设置一个 30秒的轮询监听方法,避免页面关闭
         */
        function init_start_timer() {
            //重置计数器
            timer_count = 0;
            if(interval_timer != null){
                clearInterval(interval_timer);
                interval_timer = null;
            }
            interval_timer = setInterval(function(){ myTimer() }, 30000);
        }
        /**
         *定时器具体实现方法
         */
        function myTimer() {
            //TODO 如果超过半小时没有交互,则关闭计时器
            if(timer_count >= 1800){
                clearInterval(interval_timer);
            }else {
                timer_count += 30;
                var online = '{"type":"timer","from_id":"' + from_id + '","to_id":"' + to_id + '"}';
                ws.send(online);
                console.log('timer_count',timer_count);
            }
        }
    

    然后,注意在发送消息时,比如点击发送键时首先判断用户是否在线,如果还是在线状态就再次调用 "init_start_timer()" 从而初始化定时计数

      /**
       * 判断当前用户是否 还在线
       */
      function isOnlineCurrUser() {
          if(ws.readyState == WebSocket.OPEN){
              console.log('open',ws.readyState);
              init_start_timer();
              return true;
          }else {
              console.log('close',ws.readyState);
              return false;
          }
      }
    

    补充: 有一种可能你的端口是不是被占用了,另外有可能是WebSocket传递的数据长度大于8192引起的 WebSocket建立连接后传递的JSON长度要<=8192才可以,否则就会报错 WebSocket is already in CLOSING or CLOSED state.异常然后一直在重复连接又断开。

    只要在函数中添加对状态的判断,在状态为OPEN时,执行send方法即可。方法一代码如下

    vm.init()
    if (vm.socket.readyState===1) {
        vm.send()
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(7条)

报告相同问题?

问题事件

  • 系统已结题 9月2日
  • 已采纳回答 8月25日
  • 修改了问题 8月23日
  • 创建了问题 8月23日

悬赏问题

  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 Macbookpro 连接热点正常上网,连接不了Wi-Fi。
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程
  • ¥20 我要一个分身加定位两个功能的安卓app
  • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
  • ¥15 IAR程序莫名变量多重定义