uniapp APP 端 WebSocket 使用,實現一個簡單 WebSocket 工具類

前言

最近有需求要做一個簡單業(yè)務的 APP 應用巴碗,簡單考慮選用 uniapp + uview + vue2.x 方案,因為還有web端頁面也需要用到 WebSocket 扣癣,簡單封裝了一個適應 web 端的工具惰帽,剛開始直接把 web 端的那套代碼拿過來用,跑 H5 模式調試在瀏覽器沒有父虑,打包之后問題就出來了该酗,不支持 WebSocket,當時心里咯噔一下士嚎,想著這下完了呜魄。

冷靜下來,百度查一下莱衩,原來 uniapp 基于 ECMAScript 擴展了 uni 對象爵嗅,非 H5 端不支持 window、document笨蚁、navigator 等瀏覽器專用對象睹晒。uniapp 也實現了 WebSocket ,只是 API 在 uni 對象下括细。

uni.connectSocket 相關 API 可以直接使用伪很,不過 APP 端所有 vue 頁面只能使用一個 websocket 連接。

既然有 API 那就好辦了奋单,參考 H5 的封裝改改锉试。找了好久,能參考并且比較好的文章不多览濒,那咱也寫一段吧呆盖。

參考文章

uniapp API 概述

uni.connectSocket API

uni API SocketTask 對象

uni-app框架之如何使用Websocket

uni-app中WebSocket的使用

需求目標

使用 ES6 語法封裝一個公用的 WebSocket 類,供組件使用贷笛。使用類封裝沒試過是否可以創(chuàng)建多個 WebSocket 連接应又,不過 Web 端按照這種方式封裝是可以創(chuàng)建多個連接。

實現過程

定義

在 utils 目錄昨忆,新建一個 websocket.js 文件丁频,定義 WebSocket Class,仔細查看 uniapp 文檔邑贴,調用 uni.connectSocket 接口可以返回一個 SocketTask 對象,有了這個對象之后叔磷,剩下的就是 web 端的差不多了拢驾,對象里面支持斷開自動重連。

如果需要設置重連延遲時間和重連次數可自行擴展屬性改基,目前是寫死在代碼中繁疤。

注意點:
使用 SocketTask 對象,調用存在時序問題,SocketTask.onOpen 要在 uni.connectSocket 回調調用稠腊,不然回調里的內容不會返回躁染。

調用

// index.vue
<script>
import WS from "@/utils/websocket.js"

export default {
    //...
    data() {
        return {
            ws: null
        }
    },
    onLoad() {
        this.ws && this.ws.closeSocket();
        
        this.ws = new WS(`${process.env.VUE_APP_WS_API}/ws/xxx`)
        
        // 發(fā)送數據
        // this.ws.webSocketSendMsg('發(fā)送信息')
        
        this.ws.getWebSocketMsg(data => {
            const dataJson = data;
            console.log('data', dataJson);
            if(typeof(dataJson) == "object") {
                console.log("wsObject", dataJson);
            }else {
                console.log(dataJson);
            }
        });
    },
    beforeDestroy() {
        this.ws && this.ws.closeSocket();
    },
    //...
}
</script>

主要代碼

因為 WebSocket 接收的可能是字符串或對象,又封裝了一個類型判斷函數

// @/utils/utils.js

// ...

// 判斷字符串是否為JSON格式
export function isJSON(str) {
    if (typeof str == 'string') {
        try {
            var obj = JSON.parse(str);
            if (typeof obj == 'object' && obj) {
                return true;
            } else {
                return false;
            }

        } catch (e) {
            // console.log('error:'+str+'!!!'+e);
            return false;
        }
    }
    // console.log('It is not a string!')
}

// ...

websocket.js 完整代碼

// @/utils/websocket.js
import { isJSON } from "@/utils/utils"

class WebSocketClass {
  constructor(url) {
    this.lockReconnect = false;  // 是否開始重連
    this.wsUrl = "";  // ws 地址
    this.globalCallback = null;  // 回調方法
    this.userClose = false;  // 是否主動關閉
    this.createWebSocket(url);
  }

  createWebSocket(url) {
    if (typeof (uni.connectSocket) === 'undefined') {
      this.writeToScreen("您的瀏覽器不支持WebSocket架忌,無法獲取數據");
      return false
    }

    this.wsUrl = url;
    try {
      // 創(chuàng)建一個this.ws對象吞彤,發(fā)送、接收叹放、關閉socket都由這個對象操作
      let that = this
      this.ws = uni.connectSocket({
        url: this.wsUrl,
        success(data) {
          console.log("websocket連接成功");
          
          that.initEventHandle();
        },
      });
      
    } catch (e) {
      this.reconnect(url);
    }
  }

  // 初始化
  initEventHandle() {
    // 監(jiān)聽WebSocket連接打開成功
    this.ws.onOpen(res => {
      console.log('WebSocket連接打開'); 
      

    });
    
    // 連接關閉后的回調函數
    this.ws.onClose(() => {
      if (!this.userClose) {
        this.reconnect(this.wsUrl); //重連
      }
    });
    
    // 報錯時的回調函數
    this.ws.onError(() => {
      if (!this.userClose) {
        this.reconnect(this.wsUrl); //重連
      }
    });

    // 收到服務器數據后的回調函數
    this.ws.onMessage(event => {
      if(isJSON(event.data)) {
        const jsonobject = JSON.parse(event.data)

        this.globalCallback(jsonobject)
      }else {
        this.globalCallback(event.data)
      }
    });
  }

  // 關閉ws連接回調
  reconnect(url) {
    if (this.lockReconnect) return;
    this.ws.close();
    this.lockReconnect = true;  // 關閉重連饰恕,沒連接上會一直重連,設置延遲避免請求過多
    setTimeout(() => {
      this.createWebSocket(url);
      this.lockReconnect = false;
    }, 30000);  // 重連延遲時間
  }

  // 發(fā)送信息方法
  webSocketSendMsg(msg) {
    this.ws && this.ws.send({
      data: msg,
      success() {
        console.log("消息發(fā)送成功");
      },
      fail(err) {
        console.log("關閉失敗", err)
      }
    });
  }

  // 獲取ws返回的數據方法
  getWebSocketMsg(callback) {
    this.globalCallback = callback
  }

  // 關閉ws方法
  closeSocket() {
    if (this.ws) {
      this.userClose = true;
      this.ws.close({
        success(res) {
          console.log("關閉成功", res)
        },
        fail(err) {
          console.log("關閉失敗", err)
        }
      });
    }
  }

  writeToScreen(massage) {
    console.log(massage);
  }
}
export default WebSocketClass;


實現結果

實測可用

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末井仰,一起剝皮案震驚了整個濱河市埋嵌,隨后出現的幾起案子,更是在濱河造成了極大的恐慌俱恶,老刑警劉巖雹嗦,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異合是,居然都是意外死亡俐银,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門端仰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捶惜,“玉大人,你說我怎么就攤上這事荔烧≈ㄆ撸” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵鹤竭,是天一觀的道長踊餐。 經常有香客問我,道長臀稚,這世上最難降的妖魔是什么吝岭? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮吧寺,結果婚禮上窜管,老公的妹妹穿的比我還像新娘。我一直安慰自己稚机,他們只是感情好幕帆,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赖条,像睡著了一般失乾。 火紅的嫁衣襯著肌膚如雪常熙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天,我揣著相機與錄音,去河邊找鬼协怒。 笑死,一個胖子當著我的面吹牛墓贿,可吹牛的內容都是我干的。 我是一名探鬼主播退个,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼募壕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了语盈?” 一聲冷哼從身側響起舱馅,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刀荒,沒想到半個月后代嗤,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡缠借,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年干毅,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泼返。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡硝逢,死狀恐怖,靈堂內的尸體忽然破棺而出绅喉,到底是詐尸還是另有隱情渠鸽,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布柴罐,位于F島的核電站徽缚,受9級特大地震影響,放射性物質發(fā)生泄漏革屠。R本人自食惡果不足惜凿试,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望似芝。 院中可真熱鬧那婉,春花似錦、人聲如沸国觉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽麻诀。三九已至痕寓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蝇闭,已是汗流浹背呻率。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留呻引,地道東北人礼仗。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像逻悠,于是被迫代替她去往敵國和親元践。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內容