如何高效維持網(wǎng)絡(luò)長連接:手把手教你實現(xiàn) 自適應(yīng)的心跳?;顧C制


前言

  • 當(dāng)實現(xiàn)具備實時性需求時,我們一般會選擇長連接的通信方式
  • 而在實現(xiàn)長連接方式時,存在很多性能問題,如 長連接保活
  • 今天,我將 手把手教大家實現(xiàn)自適應(yīng)的心跳?;顧C制,從而能高效維持長連接

目錄

示意圖

1. 長連接 介紹

1.1 簡介

示意圖

1.2 作用

通過 長時間保持雙方連接,從而:

  • 提高通信速度
  • 確保實時性
  • 避免短時間內(nèi)重復(fù)連接所造成的信道資源 & 網(wǎng)絡(luò)資源的浪費

1.3 長連接 與 短連接的區(qū)別

示意圖

2. 長連接斷開的原因

  • 從上節(jié)可知,在長連接的情況下,雙方的所有通信 都建立在1條長連接上(1次TCP連接);所以,長連接 需要 持續(xù)保持雙方連接 才可使得雙方持續(xù)通信

  • 可是,長連接會存在斷開的情況,而 斷開原因 主要是:

    1. 長連接所在進(jìn)程被殺死
    2. NAT超時
    3. 網(wǎng)絡(luò)狀態(tài)發(fā)生變化
    4. 其他不可抗因素(網(wǎng)絡(luò)狀態(tài)差、DHCP的租期等等 )

下面,我將對每種原因進(jìn)行分析

原因1:進(jìn)程被殺死

當(dāng)進(jìn)程被殺死后,長連接也會隨之?dāng)嚅_

原因2:NAT 超時(重點關(guān)注)

  • NAT超時現(xiàn)象如下
示意圖
  • 各運營商 & 地區(qū)的 NAT超時時間如下
示意圖
  • 特別注意:排除其他外因(網(wǎng)絡(luò)切換、NAT超時、人為原因),TCP長連接在雙方都不斷開連接的情況上,本質(zhì)上是不會自動中斷的
  1. 即,不需要心跳包來維持
  2. 驗證:讓2臺電腦連上同1個Wifi(其中1臺做服務(wù)器, 另1臺做客戶端連接服務(wù)器(無設(shè)置KeepAlive);只要電腦、路由器不斷網(wǎng)斷電,那么,2臺電腦的長連接是不會自動中斷的。

原因3:網(wǎng)絡(luò)狀態(tài)發(fā)生變化

當(dāng)移動客戶端網(wǎng)絡(luò)狀態(tài)發(fā)生變化時(如移動網(wǎng)絡(luò) & Wifi切換、斷開、重連),也會使長連接斷開

原因4:其他不可抗因素

如網(wǎng)絡(luò)狀態(tài)差、DHCP的租期到期等等,都會使得長連接發(fā)生 偶然的斷開

DHCP的租期到期:對于 Android系統(tǒng), DHCP到了租期后不會主動續(xù)約 & 繼續(xù)使用過期IP,,從而導(dǎo)致長連接 斷開


3. 高效維持長連接的解決方案

  • 在了解長連接斷開原因后,針對對應(yīng)原因,此處給出 高效維持長連接的解決方案
示意圖
  • 為此,若需有效維持長連接,則需要做到
示意圖

其實,說得簡單點:高效維持長連接的關(guān)鍵在于

  • ?;睿禾幱谶B接狀態(tài)時盡量不要斷
  • 斷線重連:斷了之后繼續(xù)重連回來

解決方案1:進(jìn)程?;?/h3>

整體概括如下:


示意圖

解決方案2:心跳?;顧C制

這是本文的重點,下節(jié)開始會詳細(xì)解析

解決方案3:斷線重連機制


4. 心跳?;顧C制簡介

  • 心跳?;顧C制的整體介紹如下
示意圖
  • 注:很多人容易混淆 心跳機制 & 輪詢機制,此處給出二者區(qū)別
示意圖

5. 主流心跳機制分析 & 對比

對國、內(nèi)外主流的移動IM產(chǎn)品(WhatsApp、Line、微信)進(jìn)行了心跳機制的簡單分析 & 對比,具體請看下圖

示意圖

6. 心跳機制方案 總體設(shè)計

下面,將根據(jù)市面上主流的心跳機制,設(shè)計 一套心跳機制方案

6.1 基本流程

示意圖

6.2 設(shè)計要點

  • 對于心跳機制方案設(shè)計的主要考慮因素 = 保證消息的實時性 & 耗費設(shè)備的資源(網(wǎng)絡(luò)流量、電量、CPU等等)
  • 從上圖可以看出,對于心跳機制方案設(shè)計的要點在于
    1. 心跳包的規(guī)格(內(nèi)容 & 大?。?/li>
    2. 心跳發(fā)送的間隔時間
    3. 斷線重連機制 (核心 = 如何 判斷長連接的有效性)

在下面的方案設(shè)計中,將針對這3個問題給出詳細(xì)的解決方案。


7. 心跳機制方案 詳細(xì)設(shè)計

7.1 心跳包的規(guī)格

為了減少流量 & 提高發(fā)送效率,需要精簡心跳包的設(shè)計

7.1.1 設(shè)計原則

主要從心跳包的內(nèi)容 & 大小入手,設(shè)計原則具體如下

示意圖

7.1.2 設(shè)計方案

心跳包 = 1個攜帶少量信息 & 大小在10字節(jié)內(nèi)的信息包


7.2 心跳發(fā)送的間隔時間

為了 防止NAT超時 & 減少設(shè)備資源的消耗(網(wǎng)絡(luò)流量、電量、CPU等等),心跳發(fā)送的間隔時間 是 整個 心跳機制方案設(shè)計的重點。

7.2.1 設(shè)計原則

心跳發(fā)送間隔時間的設(shè)計原則如下

示意圖

7.2.2 設(shè)計方案

a. 最直接 & 常用方案
  • 一般,最直接 & 常用的心跳發(fā)送間隔時間設(shè)置方案 :每隔估計 x 分鐘發(fā)送心跳包1次

  • 即 選擇 <所有NAT超時時間最短(5分鐘)的時間 即可,綜合主流移動IM產(chǎn)品,此處建議 x= 4分鐘

  • 但是,這種方案存在一些問題:

示意圖

下面,我將詳細(xì)講解 自適應(yīng)心跳間隔時間 的設(shè)計方案

b. 自適應(yīng)心跳間隔時間 設(shè)計方案
  • 基本流程
示意圖
  • 該方案需要解決的有2個核心問題:

1.如何自適應(yīng)計算心跳間隔 從而使得心跳間隔 接近 當(dāng)前NAT 超時時間?

答:不斷增加心跳間隔時間進(jìn)行心跳應(yīng)答測試,直到心跳失敗5次后,即可找出最接近 當(dāng)前NAT 超時時間的心跳間隔時間。具體請看下圖:

示意圖

注:只有當(dāng)心跳間隔 接近 NAT 超時時間 時,才能最大化平衡 長連接不中斷 & 設(shè)備資源消耗最低的問題。

2.如何檢測 當(dāng)前網(wǎng)絡(luò)環(huán)境的NAT 超時時間 發(fā)生了變化 ?

答:當(dāng)前發(fā)送心跳包成功 的最大間隔時間(即最接近NAT超時時間的心跳間隔) 發(fā)送失敗5次后,則判斷當(dāng)前網(wǎng)絡(luò)環(huán)境的NAT 超時時間 發(fā)生了變化。具體請看下圖:

示意圖

注:在檢測到 NAT 超時時間 發(fā)生變化后,重新自適應(yīng)計算心跳間隔 從而使得心跳間隔 接近 NAT 超時時間

  • 總結(jié):統(tǒng)籌2個核心問題,總結(jié)出自適應(yīng)心跳間隔時間 設(shè)計方案為下圖
示意圖

7.3 斷線重連機制

該機制的核心在于, 如何 判斷長連接的有效性

即,什么情況下視為 長連接 斷線?

7.3.1 設(shè)計原則

  • 判斷長連接是否有效的準(zhǔn)則 = 服務(wù)器是否返回心跳應(yīng)答
  • 此處需要 分清:長連接 存活 & 有效 狀態(tài)的區(qū)別:
示意圖

7.3.2 設(shè)計方案

  • 基本思路
    若連續(xù)5次發(fā)送心跳后,服務(wù)器都無心跳應(yīng)答,則視為長連接無效

通過計數(shù)計算

  • 判斷流程
示意圖

7.3.3 網(wǎng)上流傳的方案

在網(wǎng)上流傳著一些用于判斷長連接是否有效的方案,具體介紹如下

示意圖

至此,關(guān)于心跳?;顧C制已經(jīng)講解完畢。

7.4 總結(jié)

  • 設(shè)計方案
示意圖
  • 流程設(shè)計

其中,標(biāo)識 “灰色” 的判斷流程參考上文描述

示意圖

8. 優(yōu)化 & 完善

  • 上面的方案依然會存在缺陷,從而導(dǎo)致 長連接斷開

如,長連接本身不可用(此時重連多少次也沒用)

  • 下面,將優(yōu)化 & 完善上述方案,從而保證 客戶端與服務(wù)器依然保持著通信狀態(tài)

  • 優(yōu)化點

    1. 確保當(dāng)前網(wǎng)絡(luò)的有效性 & 穩(wěn)定性再開始長連接
    2. 自適應(yīng)計算心跳包間隔時間的時機

8.1 確保當(dāng)前網(wǎng)絡(luò)的有效性 & 穩(wěn)定性再開始長連接

  • 問題描述
示意圖
  • 解決方案
示意圖
  • 加入到原有 心跳?;顧C制 主流程


    示意圖

8.2 自適應(yīng)計算心跳包間隔時間的時機

  • 問題描述
示意圖
  • 方案設(shè)計
示意圖
  • 加入到原有 心跳保活機制 主流程
示意圖

8.3 總結(jié)

示意圖

9. 額外說明:TCP 協(xié)議自帶 KeepAlive 的機制 是否 可替代心跳機制

很多人認(rèn)為,TCP 協(xié)議自身就有KeepAlive機制,為何基于它的通訊鏈接,仍需 在應(yīng)用層實現(xiàn)額外的心跳?;顧C制?

9.1 回答

  • 結(jié)論:無法替代
  • 原因:TCP KeepAlive機制 的作用 是檢測連接的有無(死活),但無法檢測連接是否有效。

“連接有效”的定義 = 雙方具備發(fā)送 & 接收消息的能力

9.2 KeepAlive 機制概述

先來看看KeepAlive 機制 是什么

示意圖

9.3 具體原因

KeepAlive 的機制 不可 替代心跳機制 的具體原因如下:

示意圖

9.4 特別注意

  1. KeepAlive 機制只是操作系統(tǒng)底層的一個被動機制,不應(yīng)該被上層應(yīng)用層使用
  2. 當(dāng)系統(tǒng)關(guān)閉一個由KeepAlive 機制檢查出來的死連接時,是不會主動通知上層應(yīng)用的,只能通過調(diào)用相應(yīng)IO操作的返回值中發(fā)現(xiàn)

9.6 結(jié)論

KeepAlive機制無法代替心跳機制,需要在應(yīng)用層 自己實現(xiàn)心跳機制以檢測長連接的有效性,從而高效維持長連接


10. 實現(xiàn)方式

  • 關(guān)于該心跳?;顧C制的實現(xiàn)方案,可采用多種方案實現(xiàn)
  • Android端,本人推薦使用 Rxjava,因為:基于事件流的鏈?zhǔn)秸{(diào)用 的使用方式 使得 復(fù)雜方案 實現(xiàn)得更加優(yōu)雅、邏輯簡潔 & 使用簡單

RxJava簡介如下

示意圖

11. 總結(jié)

  • 看完本文后,相信在高效維持長連接的需求下,你可以完美地解決了?。ň唧w總結(jié)如下)
示意圖

請點贊!因為你的鼓勵是我寫作的最大動力!

相關(guān)文章閱讀
Android開發(fā):最全面、最易懂的Android屏幕適配解決方案
Android事件分發(fā)機制詳解:史上最全面、最易懂
Android開發(fā):史上最全的Android消息推送解決方案
Android開發(fā):最全面、最易懂的Webview詳解
Android開發(fā):JSON簡介及最全面解析方法!
Android四大組件:Service服務(wù)史上最全面解析
Android四大組件:BroadcastReceiver史上最全面解析


歡迎關(guān)注Carson_Ho的簡書!

不定期分享關(guān)于安卓開發(fā)的干貨,追求短、平、快,但卻不缺深度

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 當(dāng)實現(xiàn)具備實時性需求時,我們一般會選擇長連接的通信方式 而在實現(xiàn)長連接方式時,存在很多性能問題,如 長連接保...
    羽裳有涯閱讀 7,126評論 1 15
  • 互聯(lián)網(wǎng)推送服務(wù)原理:長連接+心跳機制(MQTT協(xié)議)Android推送技術(shù)研究Android實現(xiàn)推送方式解決方案a...
    合肥黑閱讀 3,267評論 0 12
  • 我搭上了一艘船。 這艘船每天冒著滾滾的濃煙,發(fā)著轟隆隆的聲響,一直破浪直前。我不知道它駛向哪里,每天,我除了看見太...
    流浪遠(yuǎn)方的喵閱讀 224評論 1 2
  • P70-89 關(guān)鍵詞:未激活、900宮格、微夢想清單、復(fù)盤、每天專注三小時 1、激活你的人生:作者把學(xué)習(xí)當(dāng)成生活的...
    UP檸檬閱讀 333評論 1 1
  • NumPy Ndarray 對象 NumPy 最重要的一個特點是其 N 維數(shù)組對象 ndarray,它是一系列同類...
    JackHCC閱讀 2,966評論 0 0

友情鏈接更多精彩內(nèi)容