1. 程式人生 > >AndroidPN訊息推送原理分析

AndroidPN訊息推送原理分析

簡介

AndroidPN:基於Asmack實現和伺服器端的持久連線,以實現伺服器對客戶端的推送,全稱為android push notification。

涉及的主要內容

  • XMPP:可擴充套件通訊和表示協議,可用於服務類實時通訊、表示和需求響應服務中的XML資料元流式傳輸
  • Asmack:適應Android使用的改進版的Smack庫,Smack庫是一個用於與XMPP伺服器進行即時通訊的類庫,包括即時訊息和群組訊息,它的存在使我們不必深入瞭解XMPP,即可完成通訊
  • Asmack中通訊主要使用的資料包型別(Packet):
    IQ: Info/Query,是基本的資訊查詢包,它被用於從伺服器獲取資訊,或將資訊設定到伺服器,包括認證、花名冊的操作、建立使用者等
    message:
    用於即時通訊的訊息
    Presence: 表示客戶端的狀態,如線上、離線、加好友、組群等
  • Mina:基於NIO的網路網路通訊應用框架

AndroidPN推送原理

所謂的推送其實就是建立客戶端和伺服器端之間的長連線,原生的Socket長連線,效能並不好,而且作為阻塞式的連線並不適合處理高併發的情景,為了解決這種問題,在JDK1.4版本中加入一個一種非阻塞式的I/O模型,這種基於通道和緩衝區的 I/O 方式被稱為NIO,但是NIO使用比較繁瑣,基本上是沒有什麼人會使用的,更多是使用封裝好的網路連線框架如Mina、Netty等,其使用方法可參見Socket、Mina簡單使用,關於AndroidPN原始碼可參見

原始碼

AndroidPN原理圖

通訊架構圖:
此圖來源於自己的理解,若是有誤,請多指教
1、客戶端和伺服器的通訊是基於XMPP協議,其通訊的方式是XML流,但是因為Asmack的存在,使得客戶端在傳送資訊時,只需要構建一個Packet物件,在Asmack內部會將Packet轉化成XML流傳送到伺服器,在伺服器端接收到XML流之後會解析成Packet物件,同理,從伺服器端向客戶端傳送訊息時也是如此,這樣我們在構建訊息時,就避免了和XMPP協議的直接對話,大大降低了難度
2、伺服器端要管理客戶端的連線,就避免不了要處理高併發的情景,因此伺服器端會比較依賴Mina框架

客戶端:
此圖來源於自己的理解,若是有誤,請多指教
1、客戶端實現推送需要具備圖中的四個模組

  • 身份驗證:用於和伺服器建立長連線
  • 監聽網路變化:用於判斷是否需要和伺服器重連
  • 監聽手機聯網狀態:其實和第二條一樣,用於重連
  • 監聽推送訊息:將推送的內容顯示到手機狀態列上

2、身份驗證其實是分成三步的,其大致的功能已在圖中標明,在連線伺服器過程中,會建立Socket,而不是使用Mina的原因是因為客戶端並不需要處理高併發的情況,只是需要一個和伺服器連線的通道而已,因此使用原生Socket即可
3、在連線伺服器階段,會初始化Reader,Writer讀寫流,這個會在後麵包裝成Asmack的讀寫流
4、註冊階段中,會構建一個Packet物件,隨機指定ID,userName,passWord傳送到伺服器,此ID就是本次的連線ID,userName和passWord就是當前裝置的賬號密碼,因此,在後臺可以全量推送訊息,也可以指定特定賬號推送訊息
5、註冊階段中,會新增一個監聽,這個監聽中添加了過濾條件,即是相同的連線ID時才可以被回撥此監聽中,而這個監聽是會儲存在一個集合中,當有訊息到來時,是先被Asmack的讀取流PacketReader接收到,之後遍歷此集合,將訊息分發出去

通訊:
此圖來源於自己的理解,若是有誤,請多指教
1、通訊模組中有兩個很重要的類PacketWriter、PacketReader負責傳送訊息和讀取訊息。它是Writre和Reader的進一步包裝,當需要傳送訊息時,會將Packet資料包放到queue佇列中,此時會notify佇列,一個一個的讀取Packet包,之後轉換成XML,呼叫內部writer將之傳送出去,若是queue佇列中沒有Packet包,則佇列一直等待,直到新資料的到來
2、在收到伺服器推送的訊息時,PacketReader會將收到的XML流轉換成對應的Packet型別資料,並根據各自的過濾條件分發出去

伺服器:
此圖來源於自己的理解,若是有誤,請多指教
1、在伺服器端的功能其實就是兩個,第一是和客戶端建立聯絡,對客戶端發來的訊息可以做出響應,第二是可以主動的向客戶端推送訊息
2、伺服器端很依賴於Mina框架,其接收處理訊息完全是標準的Mina使用方法,可以參照上面所提到的Mina的簡單使用方法
3、Mina框架是將網路連線和訊息處理各自獨立,在AndroidPN中是使用XmpploHandler處理訊息,在這個裡面可以應對:接收訊息、傳送訊息、出現異常、會話建立、會話開啟、會話閒置這6種情況,但是這裡AndroidPN在接收訊息時是利用的XmpploHandler,而在傳送訊息的時候用的是Connection類的方法
4、當客戶端傳送Packet訊息時,伺服器接收到之後,解析成不同型別的Packet,然後做出不同的響應,呼叫Connection的方法將之傳送出去,這樣在客戶端接收到之後也會做同樣的解析,轉換成不同型別的訊息

至此,AndroidPN的原理,從客戶端到伺服器端以及兩者之間的通訊簡單的分析了一下,本意是依據原始碼進行分析,但是原始碼太多,一一貼出篇幅太長,而且並不清晰,所以只能勉強剝離出各個模組加以分析,僅用於學習記憶,其中不免有誤,請多指教