search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

Android實現消息推送功能解決方案

本文介紹在Android中實現推送方式的基礎知識及相關解決方案。推送功能在手機開發中應用的場景是越來起來了,不說別的,就我們手機上的新聞客戶端就時不j時的推送過來新的消息,很方便的閱讀最新的新聞信息。這種推送功能是好的一面,但是也會經常看到很多推送過來的垃圾信息,這就讓我們感到厭煩了,關於這個我們就不能多說什麼了,畢竟很多商家要做廣告。本文就是來探討下Android中實現推送功能的一些解決方案,也希望能夠起到拋磚引玉的作用。^_^1.推送方式基礎知識:在移動互聯網時代以前的手機,如果有事情發生需要通知用戶,則會有一個窗口彈出,將告訴用戶正在發生什麼事情。可能是未接電話的提示,日曆的提醒,或是一封新的彩信。推送功能最早是被用於Email中,用來提示我們新的信息。由於時代的發展和移動互聯網的熱潮,推送功能更加地普及,已經不再僅僅用在推送郵件了,更多地用在我們的APP中了。當我們開發需要和伺服器交互的應用程序時,基本上都需要獲取伺服器端的數據,比如《地震應急通》就需要及時獲取伺服器上最新的地震信息。要獲取伺服器上不定時更新的信息,一般來說有兩種方法:第一種是客戶端使用Pull(拉)的方式,就是隔一段時間就去伺服器上獲取一下信息,看是否有更新的信息出現。第二種就是  伺服器使用Push(推送)的方式,當伺服器端有新信息了,則把最新的信息Push到客戶端上。這樣,客戶端就能自動的接收到消息。  雖然Pull和Push兩種方式都能實現獲取伺服器端更新信息的功能,但是明顯來說Push方式比Pull方式更優越。因為Pull方式更費客戶端的網路流量,更主要的是費電量,還需要我們的程序不停地去監測服務端的變化。在開發Android和iPhone應用程序時,我們往往需要從伺服器不定的向手機客戶端即時推送各種通知消息。我們只需要在Android或 IPhone的通知欄處向下一拉,就展開了Notification Panel,可以集中一覽各種各樣通知消息。目前IOS平台上已經有了比較簡單的和完美的推送通知解決方案,我會在以後詳細介紹IPhone中的解決方案,可是Android平台上實現起來卻相對比較麻煩。最近利用幾天的時間對Android的推送通知服務進行初步的研究,也希望能和大家共同探討一下。2. 幾種常見的解決方案實現原理:1)輪詢(Pull)方式:應用程序應當階段性的與伺服器進行連接並查詢是否有新的消息到達,你必須自己實現與伺服器之間的通信,例如消息排隊等。而且你還要考慮輪詢的頻率,如果太慢可能導致某些消息的延遲,如果太快,則會大量消耗網路帶寬和電池。2)SMS(Push)方式:在Android平台上,你可以通過攔截SMS消息並且解析消息內容來了解伺服器的意圖,並獲取其顯示內容進行處理。這是一個不錯的想法,我就見過採用這個方案的應用程序。這個方案的好處是,可以實現完全的實時操作。但是問題是這個方案的成本相對比較高,我們需要向移動公司繳納相應的費用。我們目前很難找到免費的短消息發送網關來實現這種方案。3)持久連接(Push)方式:這個方案可以解決由輪詢帶來的性能問題,但是還是會消耗手機的電池。IOS平台的推送服務之所以工作的很好,是因為每一台手機僅僅保持一個與伺服器之間的連接,事實上C2DM也是這麼工作的。不過剛才也講了,這個方案存在著很多的不足之處,就是我們很難在手機上實現一個可靠的服務,目前也無法與IOS平台的推送功能相比。Android操作系統允許在低內存情況下殺死系統服務,所以我們的推送通知服務很有可能就被操作系統Kill掉了。 輪詢(Pull)方式和SMS(Push)方式這兩個方案也存在明顯的不足。至於持久連接(Push)方案也有不足,不過我們可以通過良好的設計來彌補,以便於讓該方案可以有效的工作。畢竟,我們要知道GMail,GTalk以及GoogleVoice都可以實現實時更新的。3.第一種解決方案:C2DM雲端推送功能。在Android手機平台上,Google提供了C2DM(Cloudto Device  Messaging)服務,起初我就是準備採用這個服務來實現自己手機上的推送功能,並將其帶入自己的項目中。Android Cloud to Device Messaging (C2DM)是一個用來幫助開發者從伺服器向Android應用程序發送數據的服務。該服務提供了一個簡單的、輕量級的機制,允許伺服器可以通知移動應用程序直接與伺服器進行通信,以便於從伺服器獲取應用程序更新和用戶數據。C2DM服務負責處理諸如消息排隊等事務並向運行於目標設備上的應用程序分發這些消息。關於C2DM具體使用過程,大家可以去查閱相關的資料,在這裡先讓我們了解下大致方案情況。下面是C2DM操作過程示例圖: 但是經過一番研究發現,這個服務存在很大的問題: 1)C2DM內置於Android的2.2系統上,無法兼容老的1.6到2.1系統;2)C2DM需要依賴於Google官方提供的C2DM伺服器,由於國內的網路環境,這個服務經常不可用,如果想要很好的使用,我們的AppServer必須也在國外,這個恐怕不是每個開發者都能夠實現的;3) 不像在iPhone中,他們把硬體系統集成在一塊了。所以對於我們開發者來說,如果要在我們的應用程序中使用C2DM的推送功能,因為對於不同的這種硬體廠商平台,比如摩托羅拉、華為、中興做一個手機,他們可能會把Google的這種服務去掉,尤其像在國內就很多這種,把Google這種原生的服務去掉。買了一些像什麼山寨機或者是華為這種國產機,可能Google的服務就沒有了。而像在國外出的那些可能會內置。有了上述幾個方面的制約,導致我最終放棄了這個方案,不過我想利用另外一篇文章來詳細的介紹C2DM的框架以及客戶端和App Server的相應設置方法,可以作為學習資源讓我們有個參考的資料。即然C2DM無法滿足我們的要求,那麼我們就需要自己來實現Android手機客戶端與App Server之間的通信協議,保證在App Server想向指定的Android設備發送消息時,Android設備能夠及時的收到。4. 第二種解決方案:MQTT協議實現Android推送功能。採用MQTT協議實現Android推送功能也是一種解決方案。MQTT是一個輕量級的消息發布/訂閱協議,它是實現基於手機客戶端的消息推送伺服器的理想解決方案。wmqtt.jar 是IBM提供的MQTT協議的實現。我們可以從這裡(https://github.com/tokudu/AndroidPushNotificationsDemo)下載該項目的實例代碼,並且可以找到一個採用PHP書寫的伺服器端實現(https://github.com/tokudu/PhpMQTTClient)。架構如下圖所示: wmqtt.jar 是IBM提供的MQTT協議的實現。我們可以從如下站點下載(http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006)它。我們可以將該jar包加入自己的Android應用程序中。5.第三種解決方案:RSMB實現推送功能。Really Small Message Broker (RSMB) ,他是一個簡單的MQTT代理,同樣由IBM提供,其查看地址是:http://www.alphaworks.ibm.com/tech/rsmb。預設打開1883埠,應用程序當中,它負責接收來自伺服器的消息並將其轉發給指定的移動設備。SAM是一個針對MQTT寫的PHP庫。我們可以從這個http://pecl.php.net/package/sam/download/0.2.0地址下載它.send_mqtt.php是一個通過POST接收消息並且通過SAM將消息發送給RSMB的PHP腳本。6. 第四種解決方案:XMPP協議實現Android推送功能。這是我希望在項目中採用的方案,因為目前它是開源的,對於其簡單的推送功能它還是能夠實現的。我們可以修改其源代碼來適應我們的應用程序。事實上Google官方的C2DM伺服器底層也是採用XMPP協議進行的封裝。XMPP(可擴展通訊和表示協議)是基於可擴展標記語言(XML)的協議,它用於即時消息(IM)以及在線探測。這個協議可能最終允許網際網路用戶向網際網路上的其他任何人發送即時消息。關於XMPP協議我在上篇博文中已經介紹,大家可以參考下文章:http://www.cnblogs.com/hanyonglu/archive/2012/03/04/2378956.htmlandroidpn是一個基於XMPP協議的java開源Android push notification實現,我會在以後的博文中詳細介紹androidpn。它包含了完整的客戶端和伺服器端。經過源代碼研究我發現,該伺服器端基本是在另外一個開源工程openfire基礎上修改實現的,不過比較鬱悶的是androidpn的文檔是由韓語寫的,所以整個研究過程基本都是讀源碼。這是androidpn的項目主頁:http://sourceforge.net/projects/androidpn/androidpn實現意圖如下圖所示:androidpn 客戶端需要用到一個基於java的開源XMPP協議包asmack,這個包同樣也是基於openfire下的另外一個開源項目smack,不過我們不需要自己編譯,可以直接把androidpn客戶端裡面的asmack.jar拿來使用。客戶端利用asmack中提供的XMPPConnection類與服 務器建立持久連接,並通過該連接進行用戶註冊和登錄認證,同樣也是通過這條連接,接收伺服器發送的通知。androidpn伺服器端也是java語言實現的,基於openfire開源工程,不過它的Web部分採用的是spring框架,這一點與 openfire是不同的。Androidpn伺服器包含兩個部分,一個是偵聽在5222埠上的XMPP服務,負責與客戶端的 XMPPConnection類進行通信,作用是用戶註冊和身份認證,併發送推送推送通知消息。另外一部分是Web伺服器,採用一個輕量級的HTTP伺服器, 負責接收用戶的Web請求。伺服器架構如下:最上層包含四個組成部分,分別是SessionManager,Auth Manager,PresenceManager以及Notification Manager。SessionManager負責管理客戶端與伺服器之間的會話,Auth Manager負責客戶端用戶認證管理,Presence Manager負責管理客戶端用戶的登錄狀態,NotificationManager負責實現伺服器向客戶端推送消息功能。這個解決方案的最大優勢就是簡單,我們不需要象C2DM那樣依賴操作系統版本,也不會擔心某一天Google伺服器不可用。利用XMPP協議我們還可以進一步的對協議進行擴展,實現更為完善的功能。採用這個方案,我們目前只能發送文字消息,不過對於推送來說一般足夠了,因為我們不能指望通過推送得到所有的數據,一般情況下,利用推送只是告訴手機端伺服器發生了某些改變,當客戶端收到通知以後,應該主動到伺服器獲取最新的數據,這樣才是推送服務的完整實現。 XMPP協議書相對來說還是比較簡單的,值得我們進一步研究。但是在經過一段時間的測試,我發現關於androidpn也存在一些不足之處:1. 比如時間過長時,就再也收不到推送的信息了。2. 性能上也不夠穩定。 3. 如果將消息從伺服器上推送出去,就不再管理了,不管消息推送是否成功到達客戶端手機上。等等,總之,androidpn也有很多的缺點。如果我們要使用androidpn,則還需要做大量的工作。至於詳細使用過程,我們會在下個博文中再給大家介紹。7.第五種解決方案:使用第三方平台。第三方平台有商用的也有免費的,我們可以根據實現情況使用。關於國內的第三方平台,我感覺目前比較不錯的就是極光推送。關於極光推送目前是免費的,我們可以直接使用。關於詳細情況,大家可以查看它的主頁:這裡不再詳細描述。關於國外的第三方平台我也見過幾個:http://www.push-notification.org/。有興趣的朋友可以查閱相關信息。使用第三方平台就需要使用別人的伺服器,關於這點,你懂的。8.第六種解決方案:自己搭建一個推送平台。這不是一件輕鬆的工作,當然可以根據各自的需要採取合適的方案。好了,以上是關於在Android中實現推送方式的基礎知識及相關解決方案。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦