欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

瀏覽器節(jié)能機制導致Websocket斷連的坑

freeflydom
2024年4月29日 16:20 本文熱度 1175

序言

你踩過嗎?瀏覽器節(jié)能機制導致Websocket斷連的坑~~~

近期,在使用WebSocket(WS)連接時遇到了頻繁斷連的問題,這種情況在單個用戶上每天發(fā)生數(shù)百次。盡管利用了socket.io的自動重連機制能夠在斷連后迅速恢復連接,但這并不保證每一次重連都能成功接收WS消息。因此,我們進行了一些的排查和測試工作。

最終發(fā)現(xiàn)問題的根本原因:正是瀏覽器的節(jié)能機制,不經(jīng)意間成為了這一問題的幕后黑手

瀏覽器節(jié)能機制簡介

瀏覽器的節(jié)能機制逐漸成為前端開發(fā)者需要關注的問題。特別是這些節(jié)能機制可能會對定時器的精度產(chǎn)生影響,這直接關系到前端應用的用戶體驗,在某些場景下甚至影響到用戶的使用。

為了減少電能消耗,提高電池續(xù)航能力,現(xiàn)代瀏覽器都引入了節(jié)能機制。這些機制包括但不限于降低空閑標簽頁的CPU使用率、減少后臺JavaScript的執(zhí)行頻率、限制定時器的精確度等。雖然這些措施顯著提高了設備的能效,但也給前端開發(fā)帶來了一些挑戰(zhàn)。

WS頻繁斷連原因分析

查閱socket.io官網(wǎng)服務端配置的pingTimeoutpingInterval兩個參數(shù)發(fā)現(xiàn)WS心跳異常時會導致重連,具體說明:

WS連接中服務端和客戶端兩端必須一直保持心跳。如果有一端停止,則滿足如下條件之一就會自動斷連:

  • 服務器發(fā)送 ping,如果客戶端在毫秒內(nèi) pingTimeout 沒有用 pong 應答,則服務器認為連接已關閉。

  • 同樣,如果客戶端在毫秒內(nèi) pingInterval + pingTimeout 未收到來自服務器的 ping,則客戶端也會認為連接已關閉。

看文檔發(fā)現(xiàn)其實高版本的socket.io是由服務端定時發(fā)起ping。而在socket.io 2.X的版本中內(nèi)置的心跳機制是由客戶端定時發(fā)起。而瀏覽器在后臺運行時,即使你設置了一個每秒觸發(fā)的定時器,它也只能每分鐘觸發(fā)一次,超過了pingInterval + pingTimeout設置的時間,最后看到的日志是很有規(guī)律的每分鐘重連一次。在之前寫的這篇文章中也有相關的介紹《掌握Web Workers:徹底解鎖前端多線程編程的潛力》

WS頻繁斷連解決方法

@升級socket.io到最新版本

上面的截圖其實就是最新版本(4.x)的,升級后由服務器定時發(fā)起心跳。在服務端定時運行,避開了瀏覽器節(jié)能機制對定時器的影響

@自定義WS心跳事件

為了減小直接升級對已有業(yè)務的影響,目前使用的也是這種方案:在服務端自定義心跳事件,定時發(fā)送心跳custom-ping

// 客戶端的CODE

io.on('custom-ping', function () {

  io.emit('custom-pong', Date.now())

})


// 服務端CODE

io.on('connection', (socket) => {

  console.log('New client connected');


  // 發(fā)送自定義ping消息

  const pingInterval = setInterval(() => {

    socket.emit('custom-ping', Date.now());

  }, 10000); // 每10秒發(fā)送一次


  // 監(jiān)聽自定義pong消息

  socket.on('custom-pong', (data) => {

    console.log('Pong received:', data);

  });


  socket.on('disconnect', () => {

    clearInterval(pingInterval);

    console.log('Client disconnected');

  });

});


注意:斷連時一定要銷毀定時器

其實,socket.io是有內(nèi)置心跳的(2.x版本客戶端定時發(fā)起,4.x由服務端定時發(fā)起),自定義心跳的意義主要在于保持數(shù)據(jù)交換,在這個時間間隔內(nèi)保持數(shù)據(jù)交換,socket就不會自動中斷重連。

@使用setTimeout

這里要注意使用setTimeout的姿勢,如果是直接這樣使用、依然會有精度問題。

setTimeout丟失精度的情況:

// 以下setTimeout仍然會丟失精度

let _cacheTs = Date.now()

const _setTimeoutFn = () => {

  console.log('setTimeout :>> ', Date.now() - _cacheTs);

  _cacheTs = Date.now()

  setTimeout(() => {

    _setTimeoutFn()

  }, 5000)

}

_setTimeoutFn()

在setTimeout里面去執(zhí)行一個函數(shù)棧會被瀏覽器監(jiān)控到,會認為和setInterval一樣,其在后臺運行時會降低其定時精度。  但如果這樣可以避開節(jié)能機制的限制:

setTimeout不丟失精度的情況:

// 客戶端CODE

// 監(jiān)聽服務端發(fā)送的custom-pong事件

socket.on('custom-pong', onHeart)


const onHeart = () => {

  if (timer) {

    clearTimeout(pingTime.current)

  }

  timer = window.setTimeout(() => {

    socket.emit('custom-ping', Date.now())

  }, 5000)

}


// 服務端CODE

socket.on('custom-ping', ()=>{

  socket.emit('custom-pong', Date.now())

})

@使用Web-Workers

在Web-Workers線程內(nèi)發(fā)起定時不受瀏覽器節(jié)能機制的限制,相關示例在這篇文章里也有介紹《掌握Web Workers:徹底解鎖前端多線程編程的潛力》

@頁面保活(實測無效)

在后臺運行時也保持瀏覽器的活躍,用得最多的方式是在頁面隱藏一個循環(huán)播放的音頻 或者 使用nosleep.js


const noSleepInstance = new NoSleep();

document.addEventListener('click', function enableNoSleep() {

  document.removeEventListener('click', enableNoSleep, false);

  noSleepInstance.enable();

}, false);


實測,使用這種方式時,瀏覽器在后臺運行仍然存在定時器精度降低的問題

小結

WS頻繁斷連的原因:

  1. 使用了低版本(2.x)的socket.io

  2. 客戶端每5秒定時發(fā)送 心跳

  3. 瀏覽器后臺運行時觸發(fā)節(jié)能機制限制了定時器的精度,由每5秒變成了實際的每分鐘執(zhí)行一次

  4. 每分鐘執(zhí)行一次遠大于socket.io設置的pingTimeout時間

  5. WS斷開連接

  6. socket.io內(nèi)置的重連機制,立即重連成功

  7. 查看日志發(fā)現(xiàn)每分鐘重連一次。
    在實際排查中,是從第七步倒退排查發(fā)現(xiàn)是瀏覽器節(jié)能機制所引起的問題。。。

總結


作者:tager
鏈接:https://juejin.cn/post/7362576319928008755
來源:稀土掘金
著作權歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權,非商業(yè)轉(zhuǎn)載請注明出處。



該文章在 2024/4/29 16:20:37 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務費用、相關報表等業(yè)務管理,結合碼頭的業(yè)務特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved