<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【轉載】websocket斷開重連解決方案初探和實現websocket心跳重連

      https://blog.svenhetin.com/chu-tan-he-shi-xian-websocketxin-tiao-zhong-lian/
      https://www.crifan.com/websocket_ping_pong_best_interval_time/
      https://www.oschina.net/question/137225_27929

      心跳重連緣由

      websocket是前后端交互的長連接,前后端也都可能因為一些情況導致連接失效并且相互之間沒有反饋提醒。因此為了保證連接的可持續性和穩定性,websocket心跳重連就應運而生。

      在使用原生websocket的時候,如果設備網絡斷開,不會觸發websocket的任何事件函數,前端程序無法得知當前連接已經斷開。這個時候如果調用websocket.send方法,瀏覽器就會發現消息發不出去,便會立刻或者一定短時間后(不同瀏覽器或者瀏覽器版本可能表現不同)觸發onclose函數。

      后端websocket服務也可能出現異常,連接斷開后前端也并沒有收到通知,因此需要前端定時發送心跳消息ping,后端收到ping類型的消息,立馬返回pong消息,告知前端連接正常。如果一定時間沒收到pong消息,就說明連接不正常,前端便會執行重連。

      為了解決以上兩個問題,以前端作為主動方,定時發送ping消息,用于檢測網絡和前后端連接問題。一旦發現異常,前端持續執行重連邏輯,直到重連成功。

      如何實現

      在websocket實例化的時候,我們會綁定一些事件:

      var ws = new WebSocket(url);
      ws.onclose = function () {
          //something
      };
      ws.onerror = function () {
          //something
      };
              
      ws.onopen = function () {
         //something
      };
      ws.onmessage = function (event) {
         //something
      }


      如果希望websocket連接一直保持,我們會在close或者error上綁定重新連接方法。

      ws.onclose = function () {
          reconnect();
      };
      ws.onerror = function () {
          reconnect();
      };

       

      這樣一般正常情況下失去連接時,觸發onclose方法,我們就能執行重連了。

      那么針對斷網的情況的心跳重連,怎么實現呢。

      簡單的實現:

      var heartCheck = {
          timeout: 60000,//60s
          timeoutObj: null,
          reset: function(){
              clearTimeout(this.timeoutObj);
           this.start();
          },
          start: function(){
              this.timeoutObj = setTimeout(function(){
                  ws.send("HeartBeat");
              }, this.timeout)
          }
      }
      
      ws.onopen = function () {
         heartCheck.start();
      };
      ws.onmessage = function (event) {
          heartCheck.reset();
      }

       

      如上代碼,heartCheck 的 reset和start方法主要用來控制心跳的定時。

      什么條件下執行心跳:
      當onopen也就是連接上時,我們便開始start計時,如果在定時時間范圍內,onmessage獲取到了后端的消息,我們就重置倒計時,

      距離上次從后端獲取到消息超過60秒之后,執行心跳檢測,看是不是斷連了,這個檢測時間可以自己根據自身情況設定。

      判斷前端ws斷開(斷網但不限于斷網的情況):
      當心跳檢測send方法執行之后,如果當前websocket是斷開狀態(或者說斷網了),發送超時之后,瀏覽器的ws會自動觸發onclose方法,重連也執行了(onclose方法體綁定了重連事件),如果當前一直是斷網狀態,重連會2秒(時間是自己代碼設置的)執行一次直到網絡正常后連接成功。

      如此一來,我們判斷前端主動斷開ws的心跳檢測就實現了。為什么說是前端主動斷開,因為當前這種情況主要是通過前端ws的事件來判斷的,后面說后端主動斷開的情況。

      我本想測試websocket超時時間,又發現了一些新的問題

      1. 在chrome中,如果心跳檢測 也就是websocket實例執行send之后,15秒內沒發送到另一接收端,onclose便會執行。那么超時時間是15秒。

      2. 我又打開了Firefox ,Firefox在斷網7秒之后,直接執行onclose。說明在Firefox中不需要心跳檢測便能自動onclose。

      3. 同一代碼, reconnect方法 在chrome 執行了一次,Firefox執行了兩次。當然我們在幾處地方(代碼邏輯處和websocket事件處)綁定了reconnect(),

      所以保險起見,我們還是給reconnect()方法加上一個鎖,保證只執行一次

      目前來看不同的瀏覽器,有不同的機制,無論瀏覽器websocket自身會不會在斷網情況下執行onclose,加上心跳重連后,已經能保證onclose的正常觸發。

      判斷后端斷開:
      如果后端因為一些情況斷開了ws,是可控情況下的話,會下發一個斷連的消息通知,之后才會斷開,我們便會重連。

      如果因為一些異常斷開了連接,我們是不會感應到的,所以如果我們發送了心跳一定時間之后,后端既沒有返回心跳響應消息,前端又沒有收到任何其他消息的話,我們就能斷定后端主動斷開了。

      一點特別重要的發送心跳到后端,后端收到消息之后必須返回消息,否則超過60秒之后會判定后端主動斷開了。再改造下代碼:

      var heartCheck = {
          timeout: 60000,//60s
          timeoutObj: null,
          serverTimeoutObj: null,
          reset: function(){
              clearTimeout(this.timeoutObj);
              clearTimeout(this.serverTimeoutObj);
           this.start();
          },
          start: function(){
              var self = this;
              this.timeoutObj = setTimeout(function(){
                  ws.send("HeartBeat");
                  self.serverTimeoutObj = setTimeout(function(){
                      ws.close();//如果onclose會執行reconnect,我們執行ws.close()就行了.如果直接執行reconnect 會觸發onclose導致重連兩次
                  }, self.timeout)
              }, this.timeout)
          },
      }
      
      ws.onopen = function () {
         heartCheck.start();
      };
      ws.onmessage = function (event) {
          heartCheck.reset();
      }
      
      ws.onclose = function () {
          reconnect();
      };
      ws.onerror = function () {
          reconnect();
      };

       

      PS:
      因為目前我們這種方式會一直重連如果沒連接上或者斷連的話,如果有兩個設備同時登陸并且會踢另一端下線,一定要發送一個踢下線的消息類型,這邊接收到這種類型的消息,邏輯判斷后就不再執行reconnect,否則會出現一只相互擠下線的死循環。

      封裝了一個npm包,歡迎使用

      websocket-heartbeat-js(github
      websocket-heartbeat-js(npm)

      Altaba強化版

      相信隨著H5的演進,我們越來越多接觸到websocket的使用,本身就使用此技術并不難,但是在開發中會遇到各種無法預測的原因,有瀏覽器兼容問題,有后臺的意外斷開,狀態百出。

      本人前端開發遇到這樣的問題:websocket部分使用了nginx服務,默認配置是60s,就是60s,如果一直沒有數據傳輸,連接會在過了這個時間之后自動關閉。

      解決:nginx配置改為600s,前端在onclose 函數體加入判斷 然后重連

      //2017年11月27日  修改websocket連接
              var ws;//websocket實例
              var lockReconnect = false;//避免重復連接
              var wsUrl = "ws://"+'xxxxxxx';
       
              function createWebSocket(url) {
                  try {
                      if ('WebSocket' in window) {
                          ws = new WebSocket(url);
                      } else if ('MozWebSocket' in window) {
                          ws = new MozWebSocket(url);
                      } else {
                          url = "http://" + 'xxxxxxx';
                          ws = new SockJS(url);
                      }
       
                      initEventHandle();
                  } catch (e) {
                      reconnect(url);
                  }
              }
       
              function initEventHandle() {
                  ws.onclose = function (evnt) {
                      //console.log('websocket服務關閉了');
                      reconnect(wsUrl);
                  };
                  ws.onerror = function (evnt) {
                      //console.log('websocket服務出錯了');
                      reconnect(wsUrl);
                  };
                  ws.onopen = function (evnt) {
                      //心跳檢測重置
                      heartCheck.reset().start();
                  };
                  ws.onmessage = function (evnt) {
                      //如果獲取到消息,心跳檢測重置
                      //拿到任何消息都說明當前連接是正常的
                      //console.log('websocket服務獲得數據了');
       
                      //接受消息后的UI變化
                      doWithMsg(evnt.data);
                      heartCheck.reset().start();
                  }
       
                  //收到消息推送
                  function doWithMsg(msg) {
                      //......
                  }
       
              }
       
              function reconnect(url) {
                  if(lockReconnect) return;
                  lockReconnect = true;
                  //沒連接上會一直重連,設置延遲避免請求過多
                  setTimeout(function () {
                      createWebSocket(url);
                      lockReconnect = false;
                  }, 2000);
              }
       
              //心跳檢測
              var heartCheck = {
                  timeout: 60000,//60秒
                  timeoutObj: null,
                  serverTimeoutObj: null,
                  reset: function(){
                      clearTimeout(this.timeoutObj);
                      clearTimeout(this.serverTimeoutObj);
                      return this;
                  },
                  start: function(){
                      var self = this;
                      this.timeoutObj = setTimeout(function(){
                          //這里發送一個心跳,后端收到后,返回一個心跳消息,
                          //onmessage拿到返回的心跳就說明連接正常
                          ws.send("HeartBeat");
                          self.serverTimeoutObj = setTimeout(function(){//如果超過一定時間還沒重置,說明后端主動斷開了
                              ws.close();//如果onclose會執行reconnect,我們執行ws.close()就行了.如果直接執行reconnect 會觸發onclose導致重連兩次
                          }, self.timeout)
                      }, this.timeout)
                  }
              }
       
              //初始化websocket
              createWebSocket(wsUrl);

       

      致謝

      初探和實現websocket心跳重連
      websocket斷開重連解決方案,基于子慕大詩人博客修改 健壯強化版

      posted @ 2019-10-05 17:02  事理  閱讀(9849)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲成av人片天堂网无码| 国产在线观看免费观看| 男女裸交免费无遮挡全过程| 国产乱久久亚洲国产精品| 久久精产国品一二三产品| 色哟哟www网站入口成人学校| 欧美刺激性大交| 丰满少妇内射一区| 国产精品无码aⅴ嫩草| 国内精品卡一卡二卡三| 亚洲av日韩在线资源| 久久久久无码精品国产不卡| 清纯唯美人妻少妇第一页| 大渡口区| 亚洲av鲁丝一区二区三区黄| 亚洲日韩性欧美中文字幕| 国产高在线精品亚洲三区| 日韩精品av一区二区三区| 国产精品久久无码不卡黑寡妇 | 天天爱天天做天天爽夜夜揉 | 福利一区二区1000| 狠狠综合久久综合88亚洲| 亚洲国产午夜精品理论片| 无码人妻丰满熟妇啪啪网不卡| 国产精品第一二三区久久| 国产精品久久久一区二区三区| 狠狠色丁香婷婷综合尤物| 丹巴县| 成人av午夜在线观看| 性做久久久久久久| 波多野结衣高清一区二区三区| 偷拍一区二区三区在线视频| 日本免费一区二区三区最新vr | 在线看高清中文字幕一区| 中文字幕精品人妻丝袜| 无码熟妇人妻AV影音先锋| 日韩精品一区二区亚洲av| 国产va免费精品观看| 日韩精品一区二区亚洲av| 欧美xxxx做受欧美.88| 九九在线精品国产|