瀏覽器節(jié)能機(jī)制導(dǎo)致Websocket斷連的坑
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
序言你踩過嗎?瀏覽器節(jié)能機(jī)制導(dǎo)致Websocket斷連的坑~~~ 近期,在使用 最終發(fā)現(xiàn)問題的根本原因:正是瀏覽器的節(jié)能機(jī)制,不經(jīng)意間成為了這一問題的幕后黑手。 瀏覽器節(jié)能機(jī)制簡(jiǎn)介瀏覽器的節(jié)能機(jī)制逐漸成為前端開發(fā)者需要關(guān)注的問題。特別是這些節(jié)能機(jī)制可能會(huì)對(duì)定時(shí)器的精度產(chǎn)生影響,這直接關(guān)系到前端應(yīng)用的用戶體驗(yàn),在某些場(chǎng)景下甚至影響到用戶的使用。 為了減少電能消耗,提高電池續(xù)航能力,現(xiàn)代瀏覽器都引入了節(jié)能機(jī)制。這些機(jī)制包括但不限于降低空閑標(biāo)簽頁的 WS頻繁斷連原因分析查閱socket.io官網(wǎng)服務(wù)端配置的 WS連接中服務(wù)端和客戶端兩端必須一直保持心跳。如果有一端停止,則滿足如下條件之一就會(huì)自動(dòng)斷連:
看文檔發(fā)現(xiàn)其實(shí)高版本的socket.io是由服務(wù)端定時(shí)發(fā)起ping。而在socket.io 2.X的版本中內(nèi)置的心跳機(jī)制是由客戶端定時(shí)發(fā)起。而瀏覽器在后臺(tái)運(yùn)行時(shí),即使你設(shè)置了一個(gè)每秒觸發(fā)的定時(shí)器,它也只能每分鐘觸發(fā)一次,超過了 WS頻繁斷連解決方法@升級(jí)socket.io到最新版本上面的截圖其實(shí)就是最新版本(4.x)的,升級(jí)后由服務(wù)器定時(shí)發(fā)起心跳。在服務(wù)端定時(shí)運(yùn)行,避開了瀏覽器節(jié)能機(jī)制對(duì)定時(shí)器的影響 @自定義WS心跳事件為了減小直接升級(jí)對(duì)已有業(yè)務(wù)的影響,目前使用的也是這種方案:在服務(wù)端自定義心跳事件,定時(shí)發(fā)送心跳custom-ping
注意:斷連時(shí)一定要銷毀定時(shí)器 其實(shí),socket.io是有內(nèi)置心跳的(2.x版本客戶端定時(shí)發(fā)起,4.x由服務(wù)端定時(shí)發(fā)起),自定義心跳的意義主要在于保持?jǐn)?shù)據(jù)交換,在這個(gè)時(shí)間間隔內(nèi)保持?jǐn)?shù)據(jù)交換,socket就不會(huì)自動(dòng)中斷重連。 @使用setTimeout這里要注意使用setTimeout的姿勢(shì),如果是直接這樣使用、依然會(huì)有精度問題。
在setTimeout里面去執(zhí)行一個(gè)函數(shù)棧會(huì)被瀏覽器監(jiān)控到,會(huì)認(rèn)為和setInterval一樣,其在后臺(tái)運(yùn)行時(shí)會(huì)降低其定時(shí)精度。 但如果這樣可以避開節(jié)能機(jī)制的限制:
@使用Web-Workers在Web-Workers線程內(nèi)發(fā)起定時(shí)不受瀏覽器節(jié)能機(jī)制的限制,相關(guān)示例在這篇文章里也有介紹《掌握Web Workers:徹底解鎖前端多線程編程的潛力》 @頁面保活(實(shí)測(cè)無效)在后臺(tái)運(yùn)行時(shí)也保持瀏覽器的活躍,用得最多的方式是在頁面隱藏一個(gè)循環(huán)播放的音頻 或者 使用
實(shí)測(cè),使用這種方式時(shí),瀏覽器在后臺(tái)運(yùn)行仍然存在定時(shí)器精度降低的問題。 小結(jié)WS頻繁斷連的原因:
總結(jié)作者:tager 鏈接:https://juejin.cn/post/7362576319928008755 來源:稀土掘金 著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。 該文章在 2024/4/29 16:20:37 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |