日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

细说websocket快速重连机制

發(fā)布時間:2025/3/8 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 细说websocket快速重连机制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引言

在一個完善的即時通訊應(yīng)用中,websocket是極其關(guān)鍵的一環(huán),它為web應(yīng)用的客戶端和服務(wù)端提供了一種全雙工的通信機(jī)制,但由于它本身以及其底層依賴的TCP連接的不穩(wěn)定性,開發(fā)者不得不為其設(shè)計一套完整的?;睢Ⅱ灮?、重連方案,才能在實際應(yīng)用中保證應(yīng)用的即時性和高可用性。就重連而言,其速度嚴(yán)重影響了上層應(yīng)用的“即時性”和用戶體驗,試想打開網(wǎng)絡(luò)一分鐘后,微信還不能收發(fā)消息的話,是不是要抓狂?

因此,如何在網(wǎng)絡(luò)變更時快速恢復(fù)websocket的可用,就變得尤為重要。

?

快速了解websocet

Websocket誕生于2008年,在2011年成為國際標(biāo)準(zhǔn),現(xiàn)在所有的瀏覽器都已支持。它是一種全新的應(yīng)用層協(xié)議,是專門為web客戶端和服務(wù)端設(shè)計的真正的全雙工通信協(xié)議,

可以類比HTTP協(xié)議來了解websocket協(xié)議。它們的不同點:

  • HTTP的協(xié)議標(biāo)識符是http,websocket的是ws
  • HTTP請求只能由客戶端發(fā)起,服務(wù)器無法主動向客戶端推送消息,而websocket可以
  • HTTP請求有同源限制,不同源之間通信需要跨域,而websocket沒有同源限制

相同點:

  • 都是應(yīng)用層的通信協(xié)議
  • 默認(rèn)端口一樣,都是80或443
  • 都可以用于瀏覽器和服務(wù)器間的通信
  • 都基于TCP協(xié)議

兩者和TCP的關(guān)系圖:

?

重連過程拆解

首先考慮一個問題,何時需要重連?

最容易想到的是websocket連接斷了,為了接下來能收發(fā)消息,我們需要再發(fā)起一次連接。但在很多場景下,即便websocket連接沒有斷開,實際上也不可用了,比如設(shè)備切換網(wǎng)絡(luò)、鏈路中間路由崩潰、服務(wù)器負(fù)載持續(xù)過高無法響應(yīng)等,這些場景下的websocket都沒有斷開,但對上層來說,都沒辦法正常的收發(fā)數(shù)據(jù)了。因此在重連前,我們需要一種機(jī)制來感知連接是否可用、服務(wù)是否可用,而且要能快速感知,以便能夠快速從不可用狀態(tài)中恢復(fù)。

一旦感知到了連接不可用,那便可以棄舊圖新了,棄用并斷開舊連接,然后發(fā)起一次新連接。這兩個步驟看似簡單,但若想達(dá)到快,且不是那么容易的。

首先是斷開舊連接,對客戶端來說,如何快速快速斷開?協(xié)議規(guī)定客戶端必須要和服務(wù)器協(xié)商后才能斷開websocket連接,但是當(dāng)客戶端已經(jīng)聯(lián)系不上服務(wù)器、無法協(xié)商時,如何斷開并快速恢復(fù)?

其次是快速發(fā)起新連接。此快非彼快,這里的快并非是立即發(fā)起連接,立即發(fā)起連接會對服務(wù)器帶來不可預(yù)估的影響。重連時通常會采用一些退避算法,延遲一段時間后再發(fā)起重連。但如何在重連間隔和性能消耗間做出權(quán)衡?如何在“恰當(dāng)?shù)臅r間點”快速發(fā)起連接?

帶著這些疑問,我們來細(xì)看下這三個過程。

?

快速感知何時需要重連

需要重連的場景可以細(xì)分為三種,一是連接斷開了,二是連接沒斷但是不可用,三是連接對端的服務(wù)不可用了。

第一種場景很簡單,連接直接斷開了,肯定需要重連了。

而對于后兩者,無論是連接不可用,還是服務(wù)不可用,對上層應(yīng)用的影響都是不能再收發(fā)即時消息了,所以從這個角度出發(fā),感知何時需要重連的一種簡單粗暴的方法就是通過心跳包超時:發(fā)送一個心跳包,如果超過特定的時間后還沒有收到服務(wù)器回包,則認(rèn)為服務(wù)不可用,如下圖中左側(cè)的方案;這種方法最直接。那如果想要快速感知呢,就只能多發(fā)心跳包,加快心跳頻率。但是心跳太快對移動端流量、電量的消耗又會太多,所以使用這種方法沒辦法做到快速感知,可以作為檢測連接和服務(wù)可用的兜底機(jī)制。

如果要檢測連接不可用,除了用心跳檢測,還可以通過判斷網(wǎng)絡(luò)狀態(tài)來實現(xiàn),因為斷網(wǎng)、切換wifi、切換網(wǎng)絡(luò)是導(dǎo)致連接不可用的最直接原因,所以在網(wǎng)絡(luò)狀態(tài)由offline變?yōu)?/span>online時,大多數(shù)情況下需要重連下,但也不一定,因為webscoket底層是基于TCP的,TCP連接不能敏銳的感知到應(yīng)用層的網(wǎng)絡(luò)變化,所以有時候即便網(wǎng)絡(luò)斷開了一小會,對websocket連接是不會有影響的,網(wǎng)絡(luò)恢復(fù)后,仍然能夠正常地進(jìn)行通信。因此在網(wǎng)絡(luò)由斷開到連接上時,立即判斷下連接是否可用,可以通過發(fā)一個心跳包判斷,如果能夠正常收到服務(wù)器的心跳回包,則說明連接仍是可用的,如果等待超時后仍沒有收到心跳回包,則需要重連,如上圖中的右側(cè)。這種方法的優(yōu)點是速度快,在網(wǎng)絡(luò)恢復(fù)后能夠第一時間感知連接是否可用,不可用的話可以快速執(zhí)行恢復(fù),但它只能覆蓋應(yīng)用層網(wǎng)絡(luò)變化導(dǎo)致websocket不可用的情況。

綜上,定時發(fā)送心跳包檢測的方案貴在穩(wěn)定,能夠覆蓋所有場景,但速度不太可;而判斷網(wǎng)絡(luò)狀態(tài)的方案速度快,無需等待心跳間隔,較為靈敏,但覆蓋場景較為局限。因此,我們可以結(jié)合兩種方案:定時以不太快的頻率發(fā)送心跳包,比如40s/次、60s/次等,具體可以根據(jù)應(yīng)用場景來定,然后在網(wǎng)絡(luò)狀態(tài)由offline變?yōu)?/span>online時立即發(fā)送一次心跳,檢測當(dāng)前連接是否可用,不可用的話立即進(jìn)行恢復(fù)處理。這樣在大多數(shù)情況下,上層的應(yīng)用通信都能較快從不可用狀態(tài)中恢復(fù),對于少部分場景,有定時心跳作為兜底,在一個心跳周期內(nèi)也能夠恢復(fù)。

?

快速斷開舊連接

通常情況下,在發(fā)起下一次連接前,如果舊連接還存在的話,應(yīng)該先把舊連接斷開,這樣一來可以釋放客戶端和服務(wù)器的資源,二來可以避免之后誤從舊連接收發(fā)數(shù)據(jù)。

我們知道websocket底層是基于TCP協(xié)議傳輸數(shù)據(jù)的,連接兩端分別是服務(wù)器和客戶端,而TCP的TIME_WAIT狀態(tài)是由服務(wù)器端維持的,因此在大多數(shù)正常情況下,應(yīng)該由服務(wù)器發(fā)起斷開底層TCP連接,而不是客戶端。也就是說,要斷開websocket連接時,如果是服務(wù)器收到指示要斷開websocket,那它應(yīng)該立即發(fā)起斷開TCP連接;如果是客戶端收到指示要斷開websocket,那它應(yīng)該發(fā)信號給服務(wù)器,然后等待底層TCP連接被服務(wù)器斷開或直至超時。

那如果客戶端想要斷開舊的websocket,可以分websocket連接可用和不可用兩種情況來討論。當(dāng)舊連接可用時,客戶端可以直接給服務(wù)器發(fā)送斷開信號,然后服務(wù)器發(fā)起斷開連接即可;當(dāng)舊連接不可用時,比如客戶端切換了wifi,客戶端發(fā)送了斷開信號,但是服務(wù)器收不到,客戶端只能遲遲等待,直至超時才能被允許斷開。超時斷開的過程相對來說是比較久的,那有沒有辦法可以快點斷開?

上層應(yīng)用無法改變只能由服務(wù)器發(fā)起斷開連接這種協(xié)議層面的規(guī)則,所以只能從應(yīng)用邏輯入手,比如在上層通過業(yè)務(wù)邏輯保證舊連接完全失效,模擬連接斷開,然后在發(fā)起新連接,恢復(fù)通訊。這種方法相當(dāng)于嘗試斷開舊連接不行時,直接棄之,然后就能快速進(jìn)入下一流程,所以在使用時一定要確保在業(yè)務(wù)邏輯上舊連接已完全失效,比如:保證丟掉從舊連接收到所有數(shù)據(jù)、舊連接不能阻礙新連接的建立,舊連接超時斷開后不能影響新連接和上層業(yè)務(wù)邏輯等等。

?

快速發(fā)起新連接

有IM開發(fā)經(jīng)驗的同學(xué)應(yīng)該有所了解,遇到因網(wǎng)絡(luò)原因?qū)е碌闹剡B時,是萬萬不能立即發(fā)起一次新連接的,否則當(dāng)出現(xiàn)網(wǎng)絡(luò)抖動時,所有的設(shè)備都會立即同時向服務(wù)器發(fā)起連接,這無異于黑客通過發(fā)起大量請求消耗網(wǎng)絡(luò)帶寬引起的拒絕服務(wù)攻擊,這對服務(wù)器來說簡直是災(zāi)難。所以在重連時通常采用一些退避算法,延遲一段時間再發(fā)起重連,如下圖中左側(cè)的流程。

如果要快速連上呢?最直接的做法就是縮短重試間隔,重試間隔越短,在網(wǎng)絡(luò)恢復(fù)后就能越快的恢復(fù)通訊。但是太頻繁的重試對性能、帶寬、電量的消耗就比較嚴(yán)重。如何在這之間做一個較好的權(quán)衡呢?

一種比較合理的方式是隨著重試次數(shù)增多,逐漸增大重試間隔;另一方面監(jiān)聽網(wǎng)絡(luò)變化,在網(wǎng)絡(luò)狀態(tài)由offline變?yōu)?/span>online這種比較可能重連上的時刻,可以適當(dāng)?shù)販p小重連間隔,如上圖中的右側(cè)(隨重試次數(shù)的增多,重連間隔也會變大),兩種方式配合使用。

除此之外,還可以結(jié)合業(yè)務(wù)邏輯,根據(jù)成功重連上的可能性適當(dāng)?shù)恼{(diào)整間隔,如網(wǎng)絡(luò)未連接時或應(yīng)用在后臺時重連間隔可以調(diào)大一些,網(wǎng)絡(luò)正常的狀態(tài)下可以適當(dāng)調(diào)小一些等等,加快重連上的速度。

?

結(jié)尾

最后總結(jié)一下,本文在開頭將websocket斷網(wǎng)重連細(xì)分為三個步驟:確定何時需要重連、斷開舊連接和發(fā)起新連接。然后分別分析了在websocket的不同狀態(tài)下、不同的網(wǎng)絡(luò)狀態(tài)下,如何快速完成這個三個步驟:首先通過定時發(fā)送心跳包的方式檢測當(dāng)前連接是否可用,同時監(jiān)測網(wǎng)絡(luò)恢復(fù)事件,在恢復(fù)后立即發(fā)送一次心跳,快速感知當(dāng)前狀態(tài),判斷是否需要重連;其次正常情況下由服務(wù)器斷開舊連接,與服務(wù)器失去聯(lián)系時直接棄用舊連接,上層模擬斷開,來實現(xiàn)快速斷開;最后發(fā)起新連接時使用退避算法延遲一段時間再發(fā)起連接,同時考慮到資源浪費和重連速度,可以在網(wǎng)絡(luò)離線時調(diào)大重連間隔,在網(wǎng)絡(luò)正?;蚓W(wǎng)絡(luò)由offline變?yōu)?/span>online時縮小重連間隔,使之盡可能快地重連上。

參考:

  • https://tools.ietf.org/html/rfc6455
  • https://www.ruanyifeng.com/blog/2017/05/websocket.html

?

了解網(wǎng)易云信,來自網(wǎng)易核心架構(gòu)的通信與視頻云服務(wù)>>

更多技術(shù)干貨,歡迎關(guān)注vx公眾號“網(wǎng)易智慧企業(yè)技術(shù)+”。系列課程提前看,精品禮物免費得,還可直接對話CTO。

聽網(wǎng)易CTO講述前沿觀察,看最有價值技術(shù)干貨,學(xué)網(wǎng)易最新實踐經(jīng)驗。網(wǎng)易智慧企業(yè)技術(shù)+,陪你從思考者成長為技術(shù)專家。

總結(jié)

以上是生活随笔為你收集整理的细说websocket快速重连机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。