宣告:請勿直接複製貼上抄襲文章,若有需要,請規範轉載,註明出處,謝謝!
---------------------------------------------------------------------------------------------------------
最近專案中使用到了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.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,嘗試重連沒有問題,最後穩定連線,對接收訊息判斷,也沒有問題!)