websocket onclose方法什么时候触发_WebSocket断开重连解决方案,心跳重连实践
????WebSocket是前后端交互的長連接,服務器可以主動向客戶端推送信息,客戶端也可以主動向服務器發送信息,是真正的雙向平等對話,屬于服務器推送技術的一種。項目中,我們經常會使用WebSocket和服務器建立持久的連接。
????但是前后端也會因為某些不明因素鏈接斷開(我就是因為經常斷網),導致前后端都沒有反饋的情況
????
所以為了保持鏈接的穩定性和持續性,心跳重連就必須整上去了,也順便記錄一下實現心跳重連的流程
????在使用WebSocket的時候,如果網絡突然斷開,WebSocketd是不會觸發任何事件的,所以前端程序無法得知當前鏈接是否斷開。但是這個時候使用WebSocket.send方法的時候,瀏覽器會發現消息發不出去,隔一段時間之后(貌似每個瀏覽器隔的時間不相同),會觸發onclose函數。利用這點,我們可以在send不出消息并觸發onclose之后,進行重連
????當然后端也可能出現異常,他收到了這個消息,但是沒響應回來,前端也收不到通知,差不多就是你給一個人打電話,那niao人不說話的情況,問題你還不知道他在不在。所以這種情況我們要隔段時間send一次,假如超過一定時間沒收到回應,那就默認是異常了,就觸發重連。
WebSocket的各個綁定事件:
let?ws?=?new?WebSocket(url);ws.onopen = function () { //something}ws.onmessage = function (event) { //something}ws.onclose = function () { //something}ws.onerror = function () { //something}好了,按照這個思路,開始:
// 心跳檢測let heartCheck = {????timeout:?60000,?//?超時時間 timer: null, serverTimer: null, reset: function(){ clearTimeout(this.timer); this.start(); }, start: function(){ this.timer = setTimeout(function(){ ws.send('connectTest'); }, this.timeout) }}定義了一個心跳檢測,當open的時候,執行heartCheck.start()方法,然后onmessage收到信息之后調用heartCheck.reset()方法重置,這樣每次onmessage就觸發send,達到循環發送的效果。
當send失敗的時候,隔一段時間會自動觸發onclose,所以要在onclose的時候調用重連
ws.onclose = function () { console.log('onclose'); reconnect();}重連的時候需要注意防止重復連接,還要設置延遲,避免請求太頻繁
let lockReconnect = false;/** * @method reconnect ws重新連接 * @description lockReconnect防止重復連接,時間戳避免在失敗時候會頻繁建立ws連接?*/?function reconnect() { if(lockReconnect) return; lockReconnect = true; //沒連接上會一直重連,設置延遲避免請求過多 setTimeout(function () {????????createWebSocket();?//?創建webSocket連接的方法 lockReconnect = false; }, 2000);}如此上面流程就解決了如斷網send不出消息的時候重連的效果,測試的時候可以手動斷網測,親測有效
好了,現在假設后端異常,沒數據返回,onmessage就進不去,得另外想辦法。所以在每次send的時候的setTimeout內再加一個setTimeout,就是,如果里面這個setTimeout執行了,那就不等了,我覺得他是掛了,重連。
// 心跳檢測let heartCheck = { timeout: 60000, // 超時時間 timer: null, serverTimer: null, reset: function(){ clearTimeout(this.timer); clearTimeout(this.serverTimer); this.start(); }, start: function(){ let ts = this; this.timer = setTimeout(function(){ ws.send('connectTest');????????????//?超出時間內未響應就主動關閉鏈接,關閉鏈接會觸發重連 ts.serverTimer = setTimeout(function(){ ws.onclose(); }, ts.timeout) }, this.timeout) }}如果onmessage收到消息,執行了reset會清空所有的timer,重新計時, nice~~~。
這樣就完成了websocket的心跳重連,歸納一下代碼:
let lockReconnect = false; //避免重復連接let ws;// 心跳檢測let heartCheck = { timeout: 60000, timer: null, serverTimer: null, reset: function(){ clearTimeout(this.timer); clearTimeout(this.serverTimer); this.start(); }, start: function(){ let ts = this; this.timer = setTimeout(function(){ ws.send('connectTest'); ts.serverTimer = setTimeout(function(){ ws.onclose(); }, ts.timeout) }, this.timeout) }}//?創建WebSocket鏈接function createWebSocket () { if ("WebSocket" in window) { if (!url) return ws = new WebSocket(url); // WebSocket事件方法 initEventHandle(); } else { console.log('您的瀏覽器不支持websocket') }}/** * @method initEventHandle 初始化ws各個事件的方法 */function initEventHandle (url) { ws.onopen = function () { heartCheck.start(); console.log('鏈接成功:', url); } //獲得消息事件 ws.onmessage = function(data, state) { // 收到消息的時候重置倒計時????????heartCheck.reset();????????????????//something???????? } ws.onerror = function() { message('error', 'WebSocket連接錯誤!正在重連'); reconnect(); } ws.onclose = function () { console.log('onclose'); reconnect(); }}/** * @method reconnect ws重新連接 * @description lockReconnect防止重復連接,時間戳避免在失敗時候會頻繁建立ws連接 */function reconnect() { if(lockReconnect) return; lockReconnect = true; //沒連接上會一直重連,設置延遲避免請求過多 setTimeout(function () { createWebSocket(); lockReconnect = false; }, 2000);}總結
以上是生活随笔為你收集整理的websocket onclose方法什么时候触发_WebSocket断开重连解决方案,心跳重连实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python如何将批量txt文本转成批量
- 下一篇: 客户端js 读取 json 数据