關於在Vue中使用WebScoket的隨筆
- 2022 年 1 月 12 日
- 筆記
聲明:請勿直接複製粘貼抄襲文章,若有需要,請規範轉載,註明出處,謝謝!
---------------------------------------------------------------------------------------------------------
最近項目中使用到了webscoket,這個東西吧,用起來也很簡單。
但是我發現,這個東西會因為網路的不穩定而斷開連接,斷開就斷開吧,關鍵是斷開了,webscoket不會出現異常。
於是就要自己去檢測,這個有沒有掉線。
我的想法是,每隔30秒向伺服器發送資訊,
每隔32秒去判斷有沒有收到消息,如果沒有則判斷為斷開連接,進行重新連接。
因為我的技術能力還不是很強,所有程式碼在寫法上有些不足,或許有些冗餘,
但是功能的實現是沒有問題的,
話不多說,上程式碼
export default { data(){ return { path:'', // WebSocket的地址 socket:'', // WebSocket實例 times:0, // 短線重新連接次數 isConn:true, // 配合次數進行自動重連 heart:0, // 接收定時器,用來檢測WebScoket是否斷線 Tim:0, // 用於判斷是否接收消息的定時器 } }, mounted(){ this.path = 'ws://82.157.123.54:9010/ajaxchattest'; // 測試地址,百度上可以搜索到 //this.path = 'ws://' + window.location.hostname + '/devices/history'; // 獲取瀏覽器當前地址,因為後台ip可能不固定,如果固定可以寫死,就像上面那樣,但是如果ip動態,則可以使用這個,上線使用 this.Init(this.path); // 掛載時,初始化數據,建立連接等 }, methods: { Init(path){ this.socket = new WebSocket(path); // 進行連接,連接的結果和狀態在下面的onopen、onmessage、onclose let that = this; // 因為下面使用了普通函數,存在this指向問題,所以我就把vue的當前實例給that了,that的使用和this一樣,就看成this就行 this.socket.onopen = function() { console.log("WebScoket已經成功連接!"); this.heart = setInterval(()=>{ that.socket.send('hello')},1000*30); // 每隔30秒就向伺服器發送消息 that.times = 0; // 在連接成功的時候改變成初始狀態,如果重連就會增加 that.isConn = true; // 同上,與上面的次數共同控制是否重連,我不可能一直嘗試重連,連接幾百次吧 }; this.socket.onmessage = function() { // 接收消息,觸發此回調 console.log("接收到的消息為:hello"); if(that.Tim){ // 初始值為0,也就是false,第一次不會執行清理定時器 clearTimeout(that.Tim); } that.Tim = setTimeout(()=>{ that.socket.onclose=()=>{ that.socket.close() }; },1000*33) // 只要接收到消息就會創建一個定時器,定時器的內容是在33秒後關閉webscoket,但是如果在該時間內接收到消息,那麼就會再次執行,會進入上面的if, }; this.socket.onclose = function() { console.log("WebScoket已經斷開連接"); if(this.heart !== 0){ clearInterval(this.heart) } if(that.times < 5 && that.isConn){ // 每隔5秒就會重新連接,未連接成功就會次數增加,連接成功就會清零 that.isConn = false; // 在定時器結束前,不允許再次執行該函數,這裡應該可以優化 setTimeout(function(){ that.times ++; console.log(`嘗試第${that.times}次重連!`) that.isConn = true; that.Init(that.path) // 執行嘗試重新連接 },5000) }else{ this.isConn = false; // 貌似可以優化 this.socket.close(); // 徹底關閉 } }; this.socket.onerror = function() { // 這個刪了也不會報錯 console.log('WebSocket連接發生異常!'); }; }, } }
邏輯其實很簡單,就是有一點繞,聲明的變數稍微有點多,看懂了還是很簡單,
這些變數就像是一堆水龍頭,它是否放水,得要判斷,並且在不同的時候,給它不同的值。
如果不想搞懂也可以直接拿來用,關於時間地址改改就能用!
-----------------------------------------------------------------------------------------------------------------
測試的話,需要在vue文件裡面寫,打開控制台,然後斷網聯網模擬真實情況,就可以調試了
結果

(報錯是因為我手動開關了wifi,嘗試重連沒有問題,最後穩定連接,對接收消息判斷,也沒有問題!)

