長連接、心跳和斷線重連


一、概述

        目前IM軟件有一個基本的功能就是長在線,即只要有網絡就保持登錄,然而,網絡狀態是無法預測的,所以IM軟件經常會有”離線“狀態,尤其是手機客戶端。長在線這個功能依賴斷線重連完成。

        通常,網絡不穩定是造成不能長時間在線的主要原因,還有比如:服務器強制注銷客戶端、次客戶端被主客戶端踢。目前的qq和飛信都有斷線重連機制。有時候IM軟件自動完成登錄,有時候需要用戶手動登錄。所以,斷線重連是一個廣泛的概念。可以這么理解:除了從登錄界面進去的登錄,都可以稱之為斷線重連。

 

斷線重連的定義

 

        使得IM軟件能夠長在線,或者短時間內掉線,用戶無感知。

        廣義斷線重連:用戶已經成功登錄IM客戶端,用戶將程序放到后台、或者手機重啟,IM軟件再次進入前台,軟件應幫助用戶實現自動登錄。

        狹義的斷線重:客戶端的網絡狀況是不可預知的,可能從2G切換到3G或者WiFi,或者又切換到2G,甚至“飛行模式”(iOS設備)。客戶端要及時對網絡的變化做出反應,即嘗試進行登錄。

        總之:斷線重連,一般是網絡原因引起的,目的是讓IM軟件維持在線。

實現方法

        IM客戶端始終盡可能的保持連接跟服務器的連接,客戶端維護登錄狀態,以便斷線重連。從邏輯層次上來說,斷線重連的邏輯是基於登錄的邏輯的,首次登錄成功后,都有可能有斷線重連。斷線重連,實質上分為兩步:一、使客戶端斷線;二、讓客戶端重連服務器。一般來說這兩步是一個有前后順序,完整的過程。

(一)使客戶端斷線,即讓客戶端處於“未連接”狀態。以下情況將觸發這個事件:

    1.網絡切換,如從WiFi切換到4G,網絡事件。

    2.網絡連接失敗、網絡不可用。

    3.心跳失敗、心跳超時,失敗統稱心跳失敗。

    4.IM軟件后台運行即將結束。

 

(二)讓客戶端重連服務器,客戶端根據以下幾種情況實現重連服務器。

    1.ios系統“網絡可用”的通知

    2.IM軟件切換到前台,用戶觸發事件。

    3.網絡切換,如從WiFi切換到4G,網絡事件。

    4.心跳失敗的事件。

    5.客戶端重新啟動事件。

斷線重連的場景可以總結為下面幾個:

    1. 重新啟動(自動登錄)

        屬於廣義的斷線重連,需要提前加載用戶緩存,保證用戶到達主界面后能看到歷史信息。

    2. 網絡錯誤,網絡切換

        網絡連接失敗有很多種,不同的場景,客戶端要使用不同的邏輯處理。

    3. 心跳失敗

         心跳超時,失敗統稱心跳失敗。這個案例說明當前客戶端——服務器連接已經損壞,或者當前用戶身份有變化。心跳失敗后首先將客戶端離線,然后進行斷線重連操作,避免心跳失敗和網絡錯誤事件一並發生,造成兩次登錄。

    4. 網絡可達或者切換到前台

        為了避免重復登錄,當IM軟件處於“登錄成功”、“連接中”或者“已注銷”的幾個狀態的時候,客戶端忽略“網絡可達或者切換到前台”的事件。

心跳

        IM基本的底層邏輯中有“心跳”概念,即客戶端定時向Server發一個信令包,表示客戶端還“活”着。注意,是客戶端發起的。心跳是一個擬人的比喻,跟人的心跳相似。那么心跳終止了會發生什么事情呢?分為兩種情況:Server主動斷開socket,客戶端主動斷開socket。

    1. Server主動斷開socket

         Server只是接收客戶端發起的心跳。假如,Server長時間沒有收到客戶端的心跳,Server認為客戶端已經“死了”,主動斷開這個連接。此時客戶端可能就是假在線了。

    2. 客戶端斷開socket

        客戶端對待心跳,要比Server麻煩一些。客戶端要關注兩個值:

        心跳間隔值,即客戶端多長時間發一次心跳?

        心跳的超時時間。客戶端發送一次心跳,如果長時間得不到Server應答,代表網絡糟糕。客戶端需要斷開socket,主動離線。

 
      很明顯,第二點就是客戶端主動斷開的情況,一般情況下,超時時間為60秒。
      網上也有爭論:到底是否需要心跳,微信是沒有心跳的,qq和飛信有心跳。也有專家說心跳包已經影響到移動網絡,因為心跳是定時頻繁發送。

 

心跳失敗的斷線重連

 

下面是“心跳失敗”引起的斷線重連的流程圖

 

信令風暴

 

        互聯網應用的心跳包除了宣告終端在線外,還有一項重要的任務,就是提供終端的即時地址,方便應用服務器的尋址。
        有了互聯網應用的心跳機制,應用服務器可以及時下發(Push)用戶相關的信息,比如微信中的短消息、圖片或者語音等。心跳包也會帶來很多副作用,比如終端更為費電,還可能給移動通信網絡帶來信令風暴。

        看起來很完美的心跳機制,為什么會給移動網絡帶來信令風暴呢?原來,移動通信網絡中由於用戶眾多、資源稀缺,每個用戶都是動態占用資源,比如IP地址以及無線信道。每次發送心跳包,都需要移動通信網絡為用戶分配資源,分配的過程體現在信令的發送和接收上。一次心跳包的發送過程,牽涉的信令多達幾十條。
隨着互聯網APP的普及,大量的終端周期性地發送心跳包,效果類似於IP網絡中的DDOS,必然對移動通信網絡設備帶來沖擊,造成擁塞等情況,這種現象就是信令風暴。

二、安卓和ios的長連接+心跳

    互聯網推送消息的方式很常見,特別是移動互聯網上,手機每天都能收到好多推送消息,經過研究發現,這些推送服務的原理都是維護一個長連接(要不不可能達到實時效果),但普通的socket連接對服務器的消耗太大了,所以才會出現像MQTT這種輕量級低消耗的協議來維護長連接,那么要如何維護長連接呢?

    在寫之前,我們首先了解一下為什么Android維護長連接需要心跳機制,首先我們知道,維護任何一個長連接都需要心跳機制,客戶端發送一個心跳給服務器,服務器給客戶端一個心跳應答,這樣就形成客戶端服務器的一次完整的握手,這個握手是讓雙方都知道他們之間的連接是沒有斷開,客戶端是在線的。如果超過一個時間的閾值,客戶端沒有收到服務器的應答,或者服務器沒有收到客戶端的心跳,那么對客戶端來說則斷開與服務器的連接重新建立一個連接,對服務器來說只要斷開這個連接即可。那么在智能手機上的長連接心跳和在Internet上的長連接心跳有什么不同的目的呢?原因就在於智能手機使用的是移動無線網絡,那么我們在講長連接之前我們首先要了解無線移動網絡的特點。

1.無線移動網絡的特點:

    當一台智能手機連上移動網絡時,其實並沒有真正連接上Internet,運營商分配給手機的IP其實是運營商的內網IP,手機終端要連接上Internet還必須通過運營商的網關進行IP地址的轉換,這個網關簡稱為NAT(NetWork Address Translation),簡單來說就是手機終端連接Internet 其實就是移動內網IP,端口,外網IP之間相互映射。相當於在手機終端在移動無線網絡這堵牆上打個洞與外面的Internet相連。原理圖如下:(來源網絡)

 

    GGSN(GateWay GPRS Support Note 網關GPRS支持節點)模塊就實現了NAT功能,由於大部分的移動無線網絡運營商為了減少網關NAT映射表的負荷,如

果一個鏈路有一段時間沒有通信時就會刪除其對應表,造成鏈路中斷,正是這種刻意縮短空閑連接的釋放超時,原本是想節省信道資源的作用,沒想到讓互聯網

的應用不得以遠高於正常頻率發送心跳來維護推送的長連接。這也是為什么會有之前的信令風暴,微信搖收費的傳言,因為這類的應用發送心跳的頻率是很短的,

既造成了信道資源的浪費,也造成了手機電量的快速消耗。

2.android系統的推送和iOS的推送有什么區別:

    首先我們必須知道,所有的推送功能必須有一個客戶端和服務器的長連接,因為推送是由服務器主動向客戶端發送消息,如果客戶端和服務器之間不存在一個長連接那么服務器是無法來主動連接客戶端的。因而推送功能都是基於長連接的基礎是上的。

    ios長連接是由系統來維護的,也就是說蘋果的IOS系統在系統級別維護了一個客戶端和蘋果服務器的長鏈接,IOS上的所有應用上的推送都是先將消息推送到蘋果的服務器然后將蘋果服務器通過這個系統級別的長鏈接推送到手機終端上,這樣的的幾個好處為:1.在手機終端始終只要維護一個長連接即可,而且由於

這個長鏈接是系統級別的不會出現被殺死而無法推送的情況。2.省電,不會出現每個應用都各自維護一個自己的長連接。3.安全,只有在蘋果注冊的開發者才能

夠進行推送,等等。

    android的長連接是由每個應用各自維護的,但是google也推出了和蘋果技術架構相似的推送框架,C2DM,雲端推送功能,但是由於google的服務器不在中

國境內,其他的原因你懂的。所以導致這個推送無法使用,android的開發者不得不自己去維護一個長鏈接,於是每個應用如果都24小時在線,那么都得各自維

護一個長連接,這種電量和流量的消耗是可想而知的。雖然國內也出現了各種推送平台,但是都無法達到只維護一個長連接這種消耗的級別。

3.推送的實現方式:

    一:客戶端不斷的查詢服務器,檢索新內容,也就是所謂的pull 或者輪詢方式

    二:客戶端和服務器之間維持一個TCP/IP長連接,服務器向客戶端push

    三:服務器又新內容時,發送一條類似短信的信令給客戶端,客戶端收到后從服務器中下載新內容,也就是SMS的推送方式

    蘋果的推送系統和googleC2DM推送系統其實都是在系統級別維護一個TCP/IP長連接,都是基於第二種的方式進行推送的。第三種方式由於運營商沒有免費開放。這種信令導致了這種推送在成本上是無法接受的,雖然這種推送的方式非常的穩定,高效和及時。如果想了解android中各種推送方式請參考這個鏈接:Android實現推送方式解決方案 這篇博客已經介紹的非常好了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM