狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

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

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

admin
2024年11月7日 8:57 本文熱度 474

前言

最近,在使用 WebSocket(WS)連接時(shí),我們遇到了頻繁斷開連接的問題,單個(gè)用戶每天會(huì)出現(xiàn)數(shù)百次。盡管使用 socket.io 的自動(dòng)重連功能可以讓我們?cè)跀嚅_連接后迅速恢復(fù)連接,但并不能保證每次重連都能成功接收 WS 消息。因此,我們進(jìn)行了多次調(diào)查和測(cè)試。最終,我們確定了問題的根本原因:瀏覽器的節(jié)能機(jī)制,它無意中成為了問題的罪魁禍?zhǔn)住?/p>

瀏覽器節(jié)能機(jī)制概述

瀏覽器的節(jié)能機(jī)制正成為前端開發(fā)者越來越重要的考慮因素。這些機(jī)制尤其會(huì)影響定時(shí)器的精度,直接影響前端應(yīng)用的用戶體驗(yàn),在某些情況下甚至?xí)绊懣捎眯浴?/p>

為了降低功耗并延長(zhǎng)電池壽命,現(xiàn)代瀏覽器引入了節(jié)能機(jī)制。這些機(jī)制包括但不限于減少空閑標(biāo)簽的 CPU 使用率、降低后臺(tái) JavaScript 的執(zhí)行頻率以及限制定時(shí)器的精度。雖然這些措施顯著提高了設(shè)備效率,但也給前端開發(fā)帶來了一些挑戰(zhàn)。

頻繁斷開連接分析

在查看 socket.io 服務(wù)器配置中的 pingTimeout 和 pingInterval 參數(shù)時(shí),我們發(fā)現(xiàn)異常的 WS 心跳導(dǎo)致了重連。以下是詳細(xì)解釋:pingInterval(心跳間隔)

  • 默認(rèn)值:25000(25 秒)
  • 此值用于心跳機(jī)制,用于定期檢查服務(wù)器與客戶端之間的連接是否仍然存活。服務(wù)器每隔 pingInterval 毫秒發(fā)送一個(gè) ping 數(shù)據(jù)包,如果客戶端在 pingTimeout 毫秒內(nèi)沒有回復(fù) pong,服務(wù)器就認(rèn)為連接已關(guān)閉。同樣,如果客戶端在 pingInterval + pingTimeout 毫秒內(nèi)沒有收到服務(wù)器的 ping 數(shù)據(jù)包,那么客戶端也認(rèn)為連接已關(guān)閉。在這兩種情況下,斷開連接的原因都將是:ping 超時(shí)。示例代碼如下:
socket.on("disconnect", (reason) => {
  console.log(reason); // "ping timeout"
});

使用像 1000(每秒一次心跳)這樣的小值會(huì)給服務(wù)器帶來一些負(fù)載,如果有數(shù)千個(gè)連接的客戶端,這可能會(huì)變得明顯。

pingTimeout(超時(shí)時(shí)間)

  • 默認(rèn)值:20000(20 秒)
  • 見上文。
  • 注意事項(xiàng):使用較小的值意味著暫時(shí)無響應(yīng)的服務(wù)器可能會(huì)觸發(fā)大量客戶端重連。相反,使用較大的值意味著斷開的連接需要更長(zhǎng)時(shí)間才能被檢測(cè)到(如果 pingInterval + pingTimeout 大于 60 秒,在 React Native 中可能會(huì)收到警告)。

在 WS 連接中,服務(wù)器和客戶端都必須保持恒定的心跳。如果任何一方停止,只要滿足以下任一條件,連接就會(huì)自動(dòng)斷開:服務(wù)器發(fā)送 ping,如果客戶端在 pingTimeout 期間內(nèi)沒有回復(fù) pong,服務(wù)器認(rèn)為連接已關(guān)閉;同樣,如果客戶端在 pingInterval + pingTimeout 期間內(nèi)沒有收到服務(wù)器的 ping,客戶端也認(rèn)為連接已關(guān)閉。

我們發(fā)現(xiàn),在較高版本的 socket.io 中,服務(wù)器會(huì)定期發(fā)起 ping。相比之下,在 socket.io 2.X 中,內(nèi)置的心跳機(jī)制是由客戶端發(fā)起的。當(dāng)瀏覽器在后臺(tái)運(yùn)行時(shí),即使設(shè)置了每秒觸發(fā)一次的定時(shí)器,由于節(jié)能機(jī)制,它每分鐘只能觸發(fā)一次,超過了 pingInterval + pingTimeout 的設(shè)置。因此,日志顯示每分鐘都會(huì)有一次重連。

解決方案

1. 升級(jí) socket.io 到最新版本:最新版本(4.x)由服務(wù)器發(fā)起心跳,避免了瀏覽器節(jié)能機(jī)制對(duì)定時(shí)器的影響。

2. 自定義 WS 心跳事件:為了盡量減少對(duì)現(xiàn)有業(yè)務(wù)邏輯的影響,另一種解決方案是使用自定義心跳事件。服務(wù)器定期發(fā)送 custom - ping。注意:斷開連接時(shí)銷毀定時(shí)器。雖然 socket.io 有內(nèi)置心跳(2.x 中由客戶端發(fā)起,4.x 中由服務(wù)器發(fā)起),但自定義心跳有助于保持?jǐn)?shù)據(jù)交換,防止自動(dòng)斷開和重連。

客戶端代碼

io.on('custom - ping'function ({
  io.emit('custom - pong'Date.now())
})

服務(wù)器代碼

io.on('connection', (socket) => {
  console.log('New client connected');

  // 發(fā)送自定義 ping 消息
  const pingInterval = setInterval(() => {
    socket.emit('custom - ping'Date.now());
  }, 10000); // 每 10 秒

  // 監(jiān)聽自定義 pong 消息
  socket.on('custom - pong', (data) => {
    console.log('Pong received:', data);
  });

  socket.on('disconnect', () => {
    clearInterval(pingInterval);
    console.log('Client disconnected');
  });
});

注意:斷開連接時(shí)銷毀定時(shí)器。

3. 使用 setTimeout:使用 setTimeout 時(shí)要謹(jǐn)慎,因?yàn)樗匀豢赡苁ゾ取J纠a如下:

// 這個(gè) setTimeout 會(huì)失去精度
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,在后臺(tái)運(yùn)行時(shí)其精度會(huì)降低。但是,以下方法可以避免節(jié)能機(jī)制的限制: - 客戶端代碼

// 監(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ù)器代碼
socket.on('custom - ping', ()=>{
  socket.emit('custom - pong'Date.now())
})

4. 使用 Web Workers:在 Web Worker 線程中啟動(dòng)定時(shí)器不受瀏覽器節(jié)能機(jī)制的影響。

結(jié)論

隨著瀏覽器技術(shù)的發(fā)展,節(jié)能機(jī)制將變得更加精細(xì),這給前端開發(fā)帶來了新的挑戰(zhàn)。理解并適應(yīng)這些變化,并采用正確的策略來解決相關(guān)問題,對(duì)于開發(fā)高質(zhì)量的前端應(yīng)用至關(guān)重要。上述方法可以有效減輕或解決瀏覽器節(jié)能機(jī)制導(dǎo)致的定時(shí)器精度降低的影響,從而提升用戶體驗(yàn)。


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