生活随笔
收集整理的這篇文章主要介紹了
WebSocket和心跳机制
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
HTTP 協議有一個缺陷:通信只能由客戶端發起。
對一些功能需要實時獲取信息的功能就需要使用js的輪詢。就是每隔一段時間掉一次接口使用setIntval
輪詢的效率低,非常浪費資源(因為必須不停連接,或者 HTTP 連接始終打開)
WebSocket最大特點就是,服務器可以主動向客戶端推送信息,客戶端也可以主動向服務器發送信息,是真正的雙向平等對話
協議標識符是ws(如果加密,則為wss
與 HTTP 協議有著良好的兼容性。默認端口也是80和443
使用:
created () {
this.initWebSocket(this.url)
},
initWebSocket (url) {
try {
if ('WebSocket' in window) {
websocket = new WebSocket(url)
websocket.onerror = this.setErrorMessage
websocket.onopen = this.setOnopenMessage
websocket.onmessage = this.setOnmessageMessage
websocket.onclose = this.setOncloseMessage
window.onbeforeunload = this.onbeforeunload
} else {
alert('當前瀏覽器 Not support websocket')
}
} catch (e) {
this.reconnect(url)
console.log(e)
}
},
destroyed () {
websocket.close() // 離開路由之后斷開websocket連接
},
增加心跳檢測(防止斷開):
怎么使用:每隔一段時間向服務器發送消息,在message事件里面收到消息就重置心跳。
使用心跳檢測原因:由于網絡以及websocket自身的一些不穩定性,頁面長時間打開的情況下有時會發生websocket鏈接的斷開,為了防止這種情況,我們增加心跳檢測機制
實現心跳檢測的思路是:每隔一段固定的時間,向服務器端發送一個ping數據,如果在正常的情況下,服務器會返回一個pong給客戶端,如果客戶端通過
onmessage事件能監聽到的話,說明請求正常,這里我們使用了一個定時器,每隔3秒的情況下,如果是網絡斷開的情況下,在指定的時間內服務器端并沒有返回心跳響應消息,因此服務器端斷開了,因此這個時候我們使用ws.close關閉連接,在一段時間后(在不同的瀏覽器下,時間是不一樣的,firefox響應更快),
可以通過 onclose事件監聽到。因此在onclose事件內,我們可以調用 reconnect事件進行重連操作。
使用:
let ws
let lockReconnect = false;useEffect(() => {
createWebSocket()
}, [])function createWebSocket () {
try {
if ('WebSocket' in window) {
ws = new WebSocket(`ws://${process.env.WEBSITEURL}/pushWebsocketServer`);
}
initEventHandle();
} catch (e) {
reconnect();
console.log(e);
}
}function reconnect () {
if (lockReconnect) return;
lockReconnect = true;
setTimeout(function () { //沒連接上會一直重連,設置延遲避免請求過多
createWebSocket();
lockReconnect = false;
}, 2000);
}function initEventHandle () {
ws.onclose = function () {
reconnect();console.log("llws連接關閉!(可以檢測到 ws.close()關閉websocket)" + new Date().toLocaleString());
};
ws.onerror = function () {
reconnect();
console.log("llws連接錯誤!");
};
ws.onopen = function () {
heartCheck.reset().start(); //心跳檢測重置
console.log("llws連接成功!" + new Date().toLocaleString());
};
ws.onmessage = function (event) { //如果獲取到消息,心跳檢測重置,
heartCheck.reset().start(); //拿到任何消息都說明當前連接是正常的 .在這里調用reset().start()為//了先取消上次的定時器,就可以不進行關閉ws.close();了。只要接收到了pong,就說明一直連接著,一旦沒有收到pong,就不會取消定時器,就直接ws.close()關掉連接了,然后ws.onclose =function(){}可以檢測到連接被關掉,然后重新連接。console.log("llws收到消息啦:" + event.data);
if (event.data != 'pong') {
// let data = jsON.parse(event.data);
setPushNum(event.data)
}
};
}
let heartCheck = {
timeout: 1000, //1分鐘發一次心跳
timeoutObj: null,
serverTimeoutObj: null,
reset: function () {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function () {
var self = this;
this.timeoutObj = setTimeout(function () {
//這里發送一個心跳,后端收到后,返回一個心跳消息,
//onmessage拿到返回的心跳就說明連接正常
ws.send("ping");
console.log("ping!")
self.serverTimeoutObj = setTimeout(function () {//如果超過一定時間還沒重置,說明后端主動斷開了
console.log('前端使用ws.close()斷開websocket');
ws.close(); //如果onclose會執行reconnect,我們執行ws.close()就行了.如果直接執行reconnect 會觸發onclose導致重連兩次
}, self.timeout)
}, this.timeout)
}
}useEffect(() => {
window.onbeforeunload = function () {
ws.close();
}
}, [])
總結
以上是生活随笔為你收集整理的WebSocket和心跳机制的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。