小程序WebSocket實踐(心跳檢測、斷線重連)

我把小程序WebSocket的一些功能封裝成一個類坦喘,里面包括建立連接盲再、監(jiān)聽消息、發(fā)送消息瓣铣、心跳檢測答朋、斷線重連等等常用的功能。

export default class websocket {
  constructor({ heartCheck, isReconnection }) {
    // 是否連接
    this._isLogin = false;
    // 當前網(wǎng)絡(luò)狀態(tài)
    this._netWork = true;
    // 是否人為退出
    this._isClosed = false;
    // 心跳檢測頻率
    this._timeout = 3000;
    this._timeoutObj = null;
    // 當前重連次數(shù)
    this._connectNum = 0;
    // 心跳檢測和斷線重連開關(guān)棠笑,true為啟用梦碗,false為關(guān)閉
    this._heartCheck = heartCheck;
    this._isReconnection = isReconnection;
    this._onSocketOpened();
  }
  // 心跳重置
  _reset() {
    clearTimeout(this._timeoutObj);
    return this;
  }
  // 心跳開始
  _start() {
    let _this = this;
    this._timeoutObj = setInterval(() => {
      wx.sendSocketMessage({
        // 心跳發(fā)送的信息應(yīng)由前后端商量后決定
        data: JSON.stringify({
          "key": 'value'
        }),
        success(res) {
          console.log(res)
          console.log("發(fā)送心跳成功");
        },
        fail(err) {
          console.log(err)
          _this._reset()
        }
      });
    }, this._timeout);
  }
  // 監(jiān)聽websocket連接關(guān)閉
  onSocketClosed(options) {
    wx.onSocketClose(err => {
      console.log('當前websocket連接已關(guān)閉,錯誤信息為:' + JSON.stringify(err));
      // 停止心跳連接
      if (this._heartCheck) {
        this._reset();
      }
      // 關(guān)閉已登錄開關(guān)
      this._isLogin = false;
      // 檢測是否是用戶自己退出小程序
      if (!this._isClosed) {
        // 進行重連
        if (this._isReconnection) {
          this._reConnect(options)
        }
      }
      
    })
  }
  // 檢測網(wǎng)絡(luò)變化
  onNetworkChange(options) {
    wx.onNetworkStatusChange(res => {
      console.log('當前網(wǎng)絡(luò)狀態(tài):' + res.isConnected);
      if (!this._netWork) {
        this._isLogin = false;
        // 進行重連
        if (this._isReconnection) {
          this._reConnect(options)
        }
      }
    })
  }
  _onSocketOpened() {
    wx.onSocketOpen(res => {
      console.log('websocket已打開');
      // 打開已登錄開關(guān)
      this._isLogin = true;
      // 發(fā)送心跳
      if (this._heartCheck) {
        this._reset()._start();
      }
      // 發(fā)送登錄信息
      wx.sendSocketMessage({
        // 這里是第一次建立連接所發(fā)送的信息,應(yīng)由前后端商量后決定
        data: JSON.stringify({
          "key": 'value'
        })
      })
      // 打開網(wǎng)絡(luò)開關(guān)
      this._netWork = true;
    })
  }
  // 接收服務(wù)器返回的消息
  onReceivedMsg(callBack) {
    wx.onSocketMessage(msg => {
      if (typeof callBack == "function") {
        callBack(msg)
      } else {
        console.log('參數(shù)的類型必須為函數(shù)')
      }
    })
  }

  // 建立websocket連接
  initWebSocket(options) {
    let _this = this;
    if (this._isLogin) {
      console.log("您已經(jīng)登錄了");
    } else {
      // 檢查網(wǎng)絡(luò)
      wx.getNetworkType({
        success(result) {
          if (result.networkType != 'none') {
            // 開始建立連接
            wx.connectSocket({
              url: options.url,
              success(res) {
                if (typeof options.success == "function") {
                  options.success(res)
                } else {
                  console.log('參數(shù)的類型必須為函數(shù)')
                }
              },
              fail(err) {
                if (typeof options.fail == "function") {
                  options.fail(err)
                } else {
                  console.log('參數(shù)的類型必須為函數(shù)')
                }
              }
            })
          } else {
            console.log('網(wǎng)絡(luò)已斷開');
            _this._netWork = false;
            // 網(wǎng)絡(luò)斷開后顯示model
            wx.showModal({
              title: '網(wǎng)絡(luò)錯誤',
              content: '請重新打開網(wǎng)絡(luò)',
              showCancel: false,
              success: function (res) {
                if (res.confirm) {
                  console.log('用戶點擊確定')
                }
              }
            })
          }
        }
      })
    }
  }
  // 發(fā)送websocket消息
  sendWebSocketMsg(options) {
    wx.sendSocketMessage({
      data: options.data,
      success(res) {
        if (typeof options.success == "function") {
          options.success(res)
        } else {
          console.log('參數(shù)的類型必須為函數(shù)')
        }
      },
      fail(err) {
        if (typeof options.fail == "function") {
          options.fail(err)
        } else {
          console.log('參數(shù)的類型必須為函數(shù)')
        }
      }
    })
  }
  // 重連方法蓖救,會根據(jù)時間頻率越來越慢
  _reConnect(options) {
    let timer, _this = this;
    if (this._connectNum < 20) {
      timer = setTimeout(() => {
        this.initWebSocket(options)
      }, 3000)
      this._connectNum += 1;
    } else if (this._connectNum < 50) {
      timer = setTimeout(() => {
        this.initWebSocket(options)
      }, 10000)
      this._connectNum += 1;
    } else {
      timer = setTimeout(() => {
        this.initWebSocket(options)
      }, 450000)
      this._connectNum += 1;
    }
  }
  // 關(guān)閉websocket連接
  closeWebSocket(){
    wx.closeSocket();
    this._isClosed = true;
  }
}

使用方法

在app.js里面引入洪规,然后在onLaunch里面創(chuàng)建

import websocket from './utils/wechat-websocket.js'

//app.js
App({
  onLaunch() {
    let _this = this;
    // 創(chuàng)建websocket對象
    this.websocket = new websocket({
      // true代表啟用心跳檢測和斷線重連
      heartCheck: true,
      isReconnection: true
    });
    // 建立連接
    this.linkWebsocket();
    // 監(jiān)聽websocket狀態(tài)
    this.websocket.onSocketClosed({
      url: this.globalData.websocketUrl,
      success(res) { console.log(res) },
      fail(err) { console.log(err) }
    })
    // 監(jiān)聽網(wǎng)絡(luò)變化
    this.websocket.onNetworkChange({
      url: this.globalData.websocketUrl,
      success(res) { console.log(res) },
      fail(err) { console.log(err) }
    })
    // 監(jiān)聽服務(wù)器返回
    this.websocket.onReceivedMsg(result => {
      console.log('app.js收到服務(wù)器內(nèi)容:' + result.data);
      // 要進行的操作
    })
  },
  onHide(){
    // 程序后臺后的操作--關(guān)閉websocket連接
    this.websocket.closeWebSocket();
  },
  onShow(){
    // 程序從后臺到前臺的操作--建立連接
    this.linkWebsocket();
  }.
  linkWebsocket() {
    // 建立連接
    this.websocket.initWebSocket({
      url: this.globalData.websocketUrl,
      success(res) { console.log(res) },
      fail(err) { console.log(err) }
    })
  },
  getWebSocket() {
    // 向其他頁面暴露當前websocket連接
    return this.websocket;
  },
  globalData: {
    websocketUrl: 'wss://xxx.com/websocket'
  }
})
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市循捺,隨后出現(xiàn)的幾起案子斩例,更是在濱河造成了極大的恐慌,老刑警劉巖从橘,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件念赶,死亡現(xiàn)場離奇詭異,居然都是意外死亡恰力,警方通過查閱死者的電腦和手機叉谜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牺勾,“玉大人正罢,你說我怎么就攤上這事∽っ瘢” “怎么了翻具?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長回还。 經(jīng)常有香客問我裆泳,道長,這世上最難降的妖魔是什么柠硕? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任工禾,我火速辦了婚禮运提,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闻葵。我一直安慰自己民泵,他們只是感情好,可當我...
    茶點故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布槽畔。 她就那樣靜靜地躺著栈妆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪厢钧。 梳的紋絲不亂的頭發(fā)上鳞尔,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天,我揣著相機與錄音早直,去河邊找鬼寥假。 笑死,一個胖子當著我的面吹牛霞扬,可吹牛的內(nèi)容都是我干的糕韧。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼祥得,長吁一口氣:“原來是場噩夢啊……” “哼兔沃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起级及,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎额衙,沒想到半個月后饮焦,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡窍侧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年县踢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伟件。...
    茶點故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡硼啤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出斧账,到底是詐尸還是另有隱情谴返,我是刑警寧澤,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布咧织,位于F島的核電站嗓袱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏习绢。R本人自食惡果不足惜渠抹,卻給世界環(huán)境...
    茶點故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一蝙昙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梧却,春花似錦奇颠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至三椿,卻和暖如春缺菌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搜锰。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工伴郁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛋叼。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓焊傅,卻偏偏與公主長得像,于是被迫代替她去往敵國和親狈涮。 傳聞我的和親對象是個殘疾皇子狐胎,可洞房花燭夜當晚...
    茶點故事閱讀 43,566評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 點擊查看原文 Web SDK 開發(fā)手冊 SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個完善的 IM 系統(tǒng)...
    layjoy閱讀 13,702評論 0 15
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件歌馍、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,066評論 4 62
  • WebSocket 機制 WebSocket 是 HTML5 一種新的協(xié)議握巢。它實現(xiàn)了瀏覽器與服務(wù)器全雙工通信,能更...
    勇敢的_心_閱讀 2,251評論 0 4
  • WebSocket簡介 談到Web實時推送松却,就不得不說WebSocket暴浦。在WebSocket出現(xiàn)之前,很多網(wǎng)站為...
    吧啦啦小湯圓閱讀 8,129評論 15 75
  • One 最近晓锻,我換了一個時光雞的頭像 一朋友馬上在微信問我:你終于換了你那個萬年海賊王的頭像了歌焦。看你的頭像砚哆,連我這...
    Aasen阿森閱讀 314評論 1 1