亚洲乱色熟女一区二区三区丝袜,天堂√中文最新版在线,亚洲精品乱码久久久久久蜜桃图片,香蕉久久久久久av成人,欧美丰满熟妇bbb久久久

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

瀏覽器節(jié)能機(jī)制導(dǎo)致Websocket斷連的坑

admin
2024年5月7日 17:20 本文熱度 2232

序言

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

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

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

ws1.png

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

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

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

WS頻繁斷連原因分析

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

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

  • 服務(wù)器發(fā)送 ping,如果客戶端在毫秒內(nèi) pingTimeout 沒有用 pong 應(yīng)答,則服務(wù)器認(rèn)為連接已關(guān)閉。
  • 同樣,如果客戶端在毫秒內(nèi) pingInterval + pingTimeout 未收到來自服務(wù)器的 ping,則客戶端也會認(rèn)為連接已關(guān)閉。

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

WS頻繁斷連解決方法

@升級socket.io到最新版本

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

@自定義WS心跳事件

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

// 客戶端的CODE
io.on('custom-ping', function () {
 io.emit('custom-pong', Date.now())
})

// 服務(wù)端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由服務(wù)端定時發(fā)起),自定義心跳的意義主要在于保持?jǐn)?shù)據(jù)交換,在這個時間間隔內(nèi)保持?jǐn)?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)控到,會認(rèn)為和setInterval一樣,其在后臺運(yùn)行時會降低其定時精度。 但如果這樣可以避開節(jié)能機(jī)制的限制:

setTimeout不丟失精度的情況:

// 客戶端CODE
// 監(jiān)聽服務(wù)端發(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)
}

// 服務(wù)端CODE
socket.on('custom-ping', ()=>{
 socket.emit('custom-pong', Date.now())
})

@使用Web-Workers

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

@頁面?;睿▽崪y無效)

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

const noSleepInstance = new NoSleep();
document.addEventListener('click', function enableNoSleep() {
 document.removeEventListener('click', enableNoSleep, false);
 noSleepInstance.enable();
}, false);

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

小結(jié)

WS頻繁斷連的原因:

  1. 使用了低版本(2.x)的socket.io
  2. 客戶端每5秒定時發(fā)送 心跳
  3. 瀏覽器后臺運(yùn)行時觸發(fā)節(jié)能機(jī)制限制了定時器的精度,由每5秒變成了實際的每分鐘執(zhí)行一次
  4. 每分鐘執(zhí)行一次遠(yuǎn)大于socket.io設(shè)置的pingTimeout時間
  5. WS斷開連接
  6. socket.io內(nèi)置的重連機(jī)制,立即重連成功
  7. 查看日志發(fā)現(xiàn)每分鐘重連一次。
    在實際排查中,是從第七步倒退排查發(fā)現(xiàn)是瀏覽器節(jié)能機(jī)制所引起的問題。。。

總結(jié)

隨著瀏覽器技術(shù)的發(fā)展,節(jié)能機(jī)制無疑會越來越完善,但與此同時也給前端開發(fā)帶來了新的挑戰(zhàn)。了解和適應(yīng)這些變化,采用正確的策略來解決由此引起的問題,對于開發(fā)高質(zhì)量的前端應(yīng)用至關(guān)重要。通過上述方法,我們可以有效地緩解或解決瀏覽器節(jié)能機(jī)制對定時器精度降低帶來的影響,從而提升用戶體驗。

參考資料

[1]

https://socket.io/zh-CN/docs/v4/server-options/#pinginterval: https://socket.io/zh-CN/docs/v4/server-options/#pinginterval

[2]

https://juejin.cn/post/7360890308845404200: https://juejin.cn/post/7360890308845404200

[3]

https://juejin.cn/post/7360890308845404200: https://juejin.cn/post/7360890308845404200


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