公司做了個數字貨幣行情的H5,需要用到websocket,剛好自己也不會,可以學習一下,美滋滋。
項目結合vue腳手架和websocket來搭建,主要遇到了兩個問題,一個是:斷開重連機制要如何處理;另外一個是:如何在頁面上隨時的發送消息并實時接收返回的數據,斷開重連后又如何重新發送消息,接收消息
一、斷開重連機制處理 (詳細參考這里)
寫一個重連的方法(重連方法中必須加一把鎖,重連方法執行過程中不再執行重連動作,避免重復連接),然后在websocket的onclose和error中綁定重連方法,這樣一般情況下,websocket斷開或者鏈接出錯就可以實現重連了。針對斷網重連問題,就需要用心跳檢測了(主要是利用websocket定時發送消息,當超過一定時間消息還未發送成功,瀏覽器的websocket會自動觸發onclose方法,而此時onclose有綁定了重連函數,于是就觸發websocket重新連接),項目這邊暫時不考慮這個,所以沒做心跳檢測。
主要代碼:
let socket = null;let lockReconnet = false; //避免重復連接const wsUrl = '自己的websocket接口';let createSocket = url=>{ //創建socket try{ if('WebSocket' in window){ socket = new WebSocket(url) }else if('MozWebSocket' in window){ socket = new MozWebSocket(url) } initSocket() }catch(e){ reconnet(url) }}let initSocket = ()=>{ //初始化websocket socket.onopen = ()=>{ console.log('socket連接成功') //heartCheck.reset().start() //后端說暫時不需要做心跳檢測 } socket.onmessage = (ev)=>{ console.log(ev,'連接正常') //heartCheck.reset().start() //后端說暫時不需要做心跳檢測 } socket.onerror = ()=>{ console.log('websocket服務出錯了---onerror'); reconnet(wsUrl) } socket.onclose = ()=>{ console.log('websocket服務關閉了+++onclose'); reconnet(wsUrl) }}let reconnet = url=>{ //重新連接websock函數 if(lockReconnet) return false lockReconnet = true setTimeout(()=>{ createSocket(url) lockReconnet = false },2000)}let heartCheck = { //心跳檢測 timeout: 60*1000, timeoutObj: null, serverTimeoutObj: null, reset(){ clearTimeout(this.timeoutObj) clearTimeout(this.serverTimeoutObj) return this; }, start(){ let that = this; this.timeoutObj = setTimeout(()=>{ //發送數據,如果onmessage能接收到數據,表示連接正常,然后在onmessage里面執行reset方法清除定時器 socket.send('heart check') this.serverTimeoutObj = setTimeout(()=>{ socket.close() },that.timeout) },this.timeout) }}
二、在頁面上隨時發送消息并實時接收消息
在上面代碼的基礎上增加一個發送數據的方法,該方法有兩個參數,一個是需要發送的數據;另一個為接收和處理返回數據的回調函數,然后把這個方法暴露出去并掛載到Vue原型上,這樣就可以在任意頁面或者組件隨時的發送消息,并接收消息了。具體代碼:
let sendMsg = (data,callback)=>{ //發送數據,接收處理數據 if(socket.readyState===1){ globalCallback = callback; //把接收處理回調函數保存到全局 sendData = data; //把發送數據也保存到全局 data = JSON.stringify(data); socket.send(data); }else{ setTimeout(()=>{ console.log(socket,'等待socket鏈接成功') sendMsg(data,callback) },1500) return false } socket.onmessage = ev=>{ //重新監聽onmessage,并把數據傳給回調函數 callback && callback(ev) }}
新聞熱點
疑難解答
圖片精選