<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

    我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
    posts - 494, comments - 13, trackbacks - 0, articles - 1

    本文作者“Carson”,現就職于騰訊公司,原題“高效保活長連接:手把手教你實現自適應的心跳保活機制”,有較多修訂和改動。

    1、引言

    當要實現IM即時通訊聊天、消息推送等高實時性需求時,我們一般會選擇長連接的通信方式。

    而真正當實現長連接方式時,會遇到很多技術問題,比如最常見的長連接保活問題。

    今天,我將通過本篇文章,手把手教大家實現一套可自適應的心跳保活機制,從而能高效穩定地維持諸如IM聊天這類需求的長連接。

     

    學習交流:

    - 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

    - 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK 

    本文同步發布于:http://www.52im.net/thread-3908-1-1.html

    2、相關文章

    1. 為何基于TCP協議的移動端IM仍然需要心跳保活機制?
    2. 一文讀懂即時通訊應用中的網絡心跳包機制:作用、原理、實現思路等
    3. 一種Android端IM智能心跳算法的設計與實現探討(含樣例代碼)
    4. 自已開發IM有那么難嗎?手把手教你自擼一個Andriod版簡易IM (有源碼)
    5. 跟著源碼學IM(一):手把手教你用Netty實現心跳機制、斷線重連機制
    6. 跟著源碼學IM(五):正確理解IM長連接、心跳及重連機制,并動手實現

    3、什么是長連接

    認識長連接:

    長連接的主要作是通過長時間保持雙方連接,從而:

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

    長連接與短連接的區別:

    PS:對于IM這類的開發者而言,通常大家都把HTTP協議稱“短連接”、把直接基于TCPUDPWebSocket的socket稱為“長連接”。

    4、導致長連接斷開的原因

    4.1 基本概念

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

    然而,實際情況是,長連接會存在斷開的情況。

    這些斷開原因主要是:

    • 1)長連接所在進程被殺死(這主要說的是移動端);
    • 2)NAT超時;
    • 3)網絡狀態發生變化;
    • 4)其他不可抗因素(網絡狀態差、DHCP的租期等等 )。

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

    4.2 具體分析

    1)原因1:進程被殺死

    當進程被殺死后,長連接也會隨之斷開。進程被殺在Andriod端是最常見的問題,限于篇幅就不在此展開這個話題,有興趣可以閱讀這篇:《Android P正式版即將到來:后臺應用保活、消息推送的真正噩夢》。

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

    NAT超時現象如下:

     

    各運營商和地區的NAT超時時間如下:

    PS:上述數據來源于微信團隊的《移動端IM實踐:實現Android版微信的智能心跳機制》一文,隨著4G、5G的普及,這些數據有可能已發生變化,請以實際測試結果為準。

    特別注意:排除其他外因(網絡切換、NAT超時、人為原因),TCP長連接在雙方都不斷開連接的情況上,本質上是不會自動中斷的(也就是不需要心跳包來維持,可以驗證一下:讓2臺電腦連上同1個Wifi,其中1臺做服務器, 另1臺做客戶端連接服務器(無設置KeepAlive)。只要電腦、路由器不斷網斷電,那么,2臺電腦的長連接是不會自動中斷的)。

    Jack Jiang注:上述論述可能不太準確,有新興趣的讀者可以詳讀《拔掉網線再插上,TCP連接還在嗎?一文即懂!》。

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

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

    4)原因4:其他不可抗因素

    如網絡狀態差、DHCP的租期到期等等,都會使得長連接發生 偶然的斷開。DHCP的租期到期:對于 Android系統, DHCP到了租期后不會主動續約(繼續使用過期IP),從而導致長連接斷開。

    5、高效維持長連接的解決方案

    5.1 基本介紹

    在了解長連接斷開原因后,針對這些原因,此處給出我的高效維持長連接的解決方案(如下圖所示)。

    為此,若需有效維持長連接,則需要做到:

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

    • 1)保活:處于連接狀態時要做到盡量不要斷;
    • 2)重連:連接斷了之后要能繼續重連回來。

    5.2 具體措施

    1)措施1:進程保活

    整體概括如下:

    PS:關于Android的進程保活,這個話題就很熱門了,感興趣可以順著下面的文章詳細讀一讀:

    1. 應用保活終極總結(一):Android6.0以下的雙進程守護保活實踐
    2. 應用保活終極總結(二):Android6.0及以上的保活實踐(進程防殺篇)
    3. 應用保活終極總結(三):Android6.0及以上的保活實踐(被殺復活篇)
    4. Android進程保活詳解:一篇文章解決你的所有疑問
    5. 微信團隊原創分享:Android版微信后臺保活實戰分享(進程保活篇)
    6. Android P正式版即將到來:后臺應用保活、消息推送的真正噩夢
    7. 全面盤點當前Android后臺保活方案的真實運行效果(截止2019年前)
    8. 2020年了,Android后臺保活還有戲嗎?看我如何優雅的實現!
    9. 史上最強Android保活思路:深入剖析騰訊TIM的進程永生技術
    10. Android進程永生技術終極揭密:進程被殺底層原理、APP應對被殺技巧
    11. Android保活從入門到放棄:乖乖引導用戶加白名單吧(附7大機型加白示例)

    2)措施2:心跳保活機制

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

    3)措施3:斷線重連機制

    原理就是:檢測網絡狀態變化并及時判斷連接的有效性。

    具體實現:這個其實跟心跳保活機制是一套完整的邏輯,所以下面會在心跳保活機制中一起講解。

    6、心跳保活機制簡介

    心跳保活機制的整體介紹如下:

    不過,很多人容易混淆把心跳機制和傳統的HTTP輪詢機制搞混。

    下面給出二者區別:

    7、主流IM的心跳機制分析和對比

    對國、內外主流的移動IM產品(WhatsApp、Line、微信)進行了心跳機制的簡單分析和對比。

    具體請看下圖:

    PS:以上數據來自于微信團隊分享的《移動端IM實踐:WhatsApp、Line、微信的心跳策略分析》一文。

    8、心跳保活機制方案總體設計

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

    心跳機制方案的基本流程:

     

    對于心跳機制方案設計的主要考慮因素是:

    • 1)要保證消息的實時性;
    • 2)要考慮耗費設備的資源(網絡流量、電量、CPU等等)。

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

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

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

    9、心跳機制方案的詳細設計

    9.1 心跳包的規格

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

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

    設計方案:

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

    9.2 心跳發送的間隔時間

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

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

     

    9.3 最常用的心跳間隔方案

    一般,最直接且常用的心跳發送間隔時間設置方案多采用:“每隔估計 x 分鐘發送心跳包1次”。其中,x <5分鐘即可(綜合主流移動IM產品,此處建議 x= 4分鐘)。

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

    PS:關于固定心跳間隔的方案具體實現,可以詳細參考:

    1. 跟著源碼學IM(一):手把手教你用Netty實現心跳機制、斷線重連機制》;
    2. 跟著源碼學IM(五):正確理解IM長連接、心跳及重連機制,并動手實現》;
    3. 自已開發IM有那么難嗎?手把手教你自擼一個Andriod版簡易IM (有源碼)》。

    9.4 自適應心跳間隔方案

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

    基本邏輯:

     

    該方案需要解決的有2個核心問題。

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

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

    具體請看下圖:

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

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

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

    具體請看下圖:

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

    總結一下:統籌以上2個核心問題,總結出自適應心跳間隔時間設計方案為下圖:

    PS:關于自適應心跳機制的設計和實現,可以詳細參考:

    1. 移動端IM實踐:實現Android版微信的智能心跳機制》;
    2. 一種Android端IM智能心跳算法的設計與實現探討(含樣例代碼)》。

    10、斷線重連機制的實現

    技術上來說:長連接的心跳保活依賴于心跳機制,在心跳機制起作用的情況下,適時啟動斷線重連機制,在心跳機制和斷線重連機制的共同作用下才能實現真正的心跳保活。但為了讓邏輯更清晰,我把斷線重連機制跟心跳機制單獨各作為一節來講解。本節講的是斷片線重連機制。

    該機制的核心在于:如何判斷長連接的有效性。即:什么情況下視為長連接斷線?

    1)設計原則:

    基本邏輯就是:判斷長連接是否有效的準則 = 服務器是否返回心跳應答。

    此處需要分清長連接的“存活 & 有效“狀態的區別:

     

    2)具體方案:

    實現思路:通過計數計算,若連續5次發送心跳后,服務器都無心跳應答,則視為長連接無效。

    判斷流程:

    3)網上流傳的方案:

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

    至此,關于心跳保活機制已經講解完畢。

    11、方案小結

    有必要總結一下我在上兩節分享的心跳機制和斷線重連機制,這兩個機制組成了本文的長連接心跳保活完整邏輯。

    設計方案: 

    流程設計:

    注:標識 “灰色” 的判斷流程參考上文描述。

    12、進一步優化和完善心跳保活方案

    12.1 基本情況

    上兩節中的方案依然會存在技術缺陷,從而導致長連接斷開(比如:長連接本身不可用(此時重連多少次也沒用))。

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

    優化點主要是:

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

    12.2 確保網絡的有效性和穩定性后再開始長連接

    問題描述:

     

    解決方案:

    加入到原有的心跳保活機制主流程:

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

    問題描述:

     

    方案設計:

     

    加入到到原有的心跳保活機制主流程:

     

    12.4 小結一下

    13、額外思考:TCP協議自帶的KeepAlive機制能否替代心跳機制?

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

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

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

    先來看看KeepAlive 機制是什么:

     

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

     

    特別注意:

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

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

    Jack Jiang注:關于TCP本身的KeepAlive機制,可能詳讀:

    1. 為何基于TCP協議的移動端IM仍然需要心跳保活機制?
    2. 徹底搞懂TCP協議層的KeepAlive保活機制

    14、本文總結

    看完本文后,相信在高效維持長連接的需求下,你可以完美地解決了!

    本文方案的主體設計就是:

    方案的優化和完善內容就是:

    15、參考資料

    [1] TCP/IP詳解 卷1:協議

    [2] 為何基于TCP協議的移動端IM仍然需要心跳保活機制?

    [3] 徹底搞懂TCP協議層的KeepAlive保活機制

    [4] 萬字長文,一篇吃透WebSocket:概念、原理、易錯常識、動手實踐

    [5] 移動端IM實踐:實現Android版微信的智能心跳機制

    [6] 移動端IM實踐:WhatsApp、Line、微信的心跳策略分析

    [7] 微信團隊原創分享:Android版微信后臺保活實戰分享(網絡保活篇)

    [8] 融云技術分享:融云安卓端IM產品的網絡鏈路保活技術實踐

    [9] 阿里IM技術分享(五):閑魚億級IM消息系統的及時性優化實踐

    [10] 2020年了,Android后臺保活還有戲嗎?看我如何優雅的實現!

    (本文同步發布于:http://www.52im.net/thread-3908-1-1.html



    作者:Jack Jiang (點擊作者姓名進入Github)
    出處:http://www.52im.net/space-uid-1.html
    交流:歡迎加入即時通訊開發交流群 215891622
    討論:http://www.52im.net/
    Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 亚洲午夜精品在线| 国产精品亚洲不卡一区二区三区| 亚洲精品无码久久久久去q| 色欲aⅴ亚洲情无码AV蜜桃| 手机看片久久国产免费| 亚洲国产精品网站在线播放| 免费可以在线看A∨网站| 亚洲免费网站在线观看| 成年女人免费v片| 精品韩国亚洲av无码不卡区| 国产国产人免费人成免费视频| 国产精品亚洲а∨天堂2021 | 久久丫精品国产亚洲av| 永久在线观看www免费视频| 亚洲国产最大av| 四虎永久在线精品免费影视| 免费播放美女一级毛片| 久久亚洲2019中文字幕| 久久永久免费人妻精品| 亚洲另类古典武侠| 免费国产成人午夜私人影视| a级毛片免费完整视频| 亚洲毛片无码专区亚洲乱| 国产精品69白浆在线观看免费| 亚洲AV成人影视在线观看| 亚洲?v女人的天堂在线观看| 抽搐一进一出gif免费视频| 亚洲人成依人成综合网| 猫咪社区免费资源在线观看| 鲁啊鲁在线视频免费播放| 亚洲大尺度无码无码专区| 一二三四影视在线看片免费| 日本一区二区三区在线视频观看免费 | 亚洲国产成人片在线观看| 国产国产人免费视频成69堂| 菠萝菠萝蜜在线免费视频| 久久亚洲AV无码精品色午夜麻| 最近中文字幕无吗免费高清| 日韩精品无码永久免费网站| 久久av无码专区亚洲av桃花岛| 午夜精品在线免费观看|