iOS 長連接 KeepAlive

前言

  • 當實現具備實時性需求時,我們一般會選擇長連接的通信方式
  • 而在實現長連接方式時,存在很多性能問題,如 長連接?;?/li>
  • 今天,我將 實現自適應的心跳?;顧C制,從而能高效維持長連接

目錄

圖片.png

1. 長連接 介紹

1.1 簡介

圖片.png

1.2 作用

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

  • 提高通信速度
  • 確保實時性
  • 避免短時間內重復連接所造成的信道資源 & 網絡資源的浪費

1.3 長連接 與 短連接的區別

圖片.png

2. 長連接斷開的原因

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

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

    1. 長連接所在進程被殺死
    2. NAT超時
    3. 網絡狀態發生變化
    4. 其他不可抗因素(網絡狀態差、DHCP的租期等等 )

下面,我將對每種原因進行分析

原因1:進程被殺死

當進程被殺死后,長連接也會隨之斷開

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

  • NAT超時現象如下


    圖片.png
  • 各運營商 & 地區的 NAT超時時間如下
圖片.png
  • 特別注意:排除其他外因(網絡切換、NAT超時、人為原因),TCP長連接在雙方都不斷開連接的情況上,本質上是不會自動中斷的

    1. 即,不需要心跳包來維持

    2. 驗證:讓2臺電腦連上同1個Wifi(其中1臺做服務器, 另1臺做客戶端連接服務器(無設置KeepAlive);只要電腦、路由器不斷網斷電,那么,2臺電腦的長連接是不會自動中斷的。

原因3:網絡狀態發生變化

當移動客戶端網絡狀態發生變化時(如移動網絡 & Wifi切換、斷開、重連),也會使長連接斷開

原因4:其他不可抗因素

如網絡狀態差、DHCP的租期到期等等,都會使得長連接發生 偶然的斷開

DHCP的租期到期:對于 Android系統, DHCP到了租期后不會主動續約 & 繼續使用過期IP,,從而導致長連接 斷開

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

  • 在了解長連接斷開原因后,針對對應原因,此處給出 高效維持長連接的解決方案
圖片.png
  • 為此,若需有效維持長連接,則需要做到
圖片.png

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

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

解決方案1:進程?;?/h3>

整體概括如下:


圖片.png

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

這是本文的重點,下節開始會詳細解析

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

  • 原理
    檢測網絡狀態變化 & 判斷連接的有效性
  • 具體實現
    前者請參考文章:Android:檢測網絡狀態&監聽網絡變化;后者主要存在于心跳?;顧C制,所以下面會在心跳保活機制中一起講解。

4. 心跳?;顧C制簡介

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

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

對國、內外主流的移動IM產品(WhatsAppLine、微信)進行了心跳機制的簡單分析 & 對比,具體請看下圖

圖片.png

6. 心跳機制方案 總體設計

下面,將根據市面上主流的心跳機制,設計 一套心跳機制方案

6.1 基本流程

圖片.png

6.2 設計要點

  • 對于心跳機制方案設計的主要考慮因素 = 保證消息的實時性 & 耗費設備的資源(網絡流量、電量、CPU等等)

  • 從上圖可以看出,對于心跳機制方案設計的要點在于

    1. 心跳包的規格(內容 & 大小)
    2. 心跳發送的間隔時間
    3. 斷線重連機制 (核心 = 如何 判斷長連接的有效性)

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

7. 心跳機制方案 詳細設計

7.1 心跳包的規格

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

7.1.1 設計原則

主要從心跳包的內容 & 大小入手,設計原則具體如下

圖片.png

7.1.2 設計方案

心跳包 = 1個攜帶少量信息 & 大小在10字節內的信息包

7.2 心跳發送的間隔時間

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

7.2.1 設計原則

心跳發送間隔時間的設計原則如下

圖片.png

7.2.2 設計方案

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

    其中,x <5分鐘即可。(綜合主流移動IM產品,此處建議 x= 4分鐘)

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

圖片.png

下面,我將詳細講解 自適應心跳間隔時間 的設計方案

b. 自適應心跳間隔時間 設計方案
  • 基本流程
圖片.png
  • 該方案需要解決的有2個核心問題:

1.如何自適應計算心跳間隔 從而使得心跳間隔 接近 當前NAT 超時時間?

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

圖片.png

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

2.如何檢測 當前網絡環境的NAT 超時時間 發生了變化 ?

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

圖片.png

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

  • 總結:統籌2個核心問題,總結出自適應心跳間隔時間 設計方案為下圖
圖片.png

7.3 斷線重連機制

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

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

7.3.1 設計原則

  • 判斷長連接是否有效的準則 = 服務器是否返回心跳應答
  • 此處需要 分清:長連接 存活 & 有效 狀態的區別:
圖片.png

7.3.2 設計方案

  • 基本思路
    若連續5次發送心跳后,服務器都無心跳應答,則視為長連接無效

    通過計數計算

  • 判斷流程

圖片.png

7.3.3 網上流傳的方案

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

圖片.png

至此,關于心跳?;顧C制已經講解完畢。

7.4 總結

  • 設計方案
圖片.png
  • 流程設計

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

圖片.png

8. 優化 & 完善

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

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

  • 下面,將優化 & 完善上述方案,從而保證 客戶端與服務器依然保持著通信狀態

  • 優化點

    1. 確保當前網絡的有效性 & 穩定性再開始長連接
    2. 自適應計算心跳包間隔時間的時機

8.1 確保當前網絡的有效性 & 穩定性再開始長連接

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


    圖片.png

8.2 自適應計算心跳包間隔時間的時機

  • 問題描述
圖片.png
  • 方案設計
圖片.png
  • 加入到原有 心跳保活機制 主流程
圖片.png

8.3 總結

圖片.png

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

很多人認為,TCP 協議自身就有KeepAlive機制,為何基于它的通訊鏈接,仍需 在應用層實現額外的心跳保活機制

9.1 回答

  • 結論:無法替代

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

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

9.2 KeepAlive 機制概述

先來看看KeepAlive 機制 是什么

圖片.png

9.3 具體原因

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

圖片.png

9.4 特別注意

  1. KeepAlive 機制只是操作系統底層的一個被動機制,不應該被上層應用層使用

    1. 當系統關閉一個由KeepAlive 機制檢查出來的死連接時,是不會主動通知上層應用的,只能通過調用相應IO操作的返回值中發現

9.6 結論

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

10. 總結

  • 看完本文后,相信在高效維持長連接的需求下,你可以完美地解決了?。ň唧w總結如下)
圖片.png
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容