【轉載】Android推送方案分析(MQTT/XMPP/GCM)

http://m.oschina.net/blog/82059php

本文主旨在於,對目前Android平臺上最主流的幾種消息推送方案進行分析和對比,比較客觀地反映出這些推送方案的優缺點,幫助你們選擇最合適的實施方案。 

方案一、 使用GCM服務(Google Cloud Messaging) 
簡介:Google推出的雲消息服務,即第二代的G2DM。 
優勢:Google提供的服務、原生、簡單,無需實現和部署服務端。 
缺點:Android版本限制(必須大於2.2版本),該服務在國內不夠穩定、須要用戶綁定Google賬號,受限於Google。 

方案二、 使用XMPP協議(Openfire + Spark + Smack) 
簡介:基於XML協議的通信協議,前身是Jabber,目前已由IETF國際標準化組織完成了標準化工做。 
優勢:協議成熟、強大、可擴展性強、目前主要應用於許多聊天系統中,且已有開源的Java版的開發實例androidpn。 
缺點:協議較複雜、冗餘(基於XML)、費流量、費電,部署硬件成本高。 

方案三、 使用MQTT協議(更多信息見: http://mqtt.org/ ) 
簡介:輕量級的、基於代理的「發佈/訂閱」模式的消息傳輸協議。 
優勢:協議簡潔、小巧、可擴展性強、省流量、省電,目前已經應用到企業領域(參考: http://mqtt.org/software ),且已有C++版的服務端組件rsmb。 
缺點:不夠成熟、實現較複雜、服務端組件rsmb不開源,部署硬件成本較高。 

方案四、 使用HTTP輪循方式 
簡介:定時向HTTP服務端接口(Web Service API)獲取最新消息。 
優勢:實現簡單、可控性強,部署硬件成本低。 
缺點:實時性差。 

對各個方案的優缺點的研究和對比,推薦使用MQTT協議的方案進行實現,主要緣由是: MQTT最快速,也最省流量(固定頭長度僅爲2字節),且極易擴展,適合二次開發 。接下來,咱們就來分析使用MQTT方案進行Android消息的原理和方法,並架設本身的推送服務。 

一、推送原理分析
 

 

實際上,其餘推送系統(包括GCM、XMPP方案)的原理都與此相似。 

二、推送服務端準備 

a> 下載&解壓rsmb安裝包(下載地址: http://www.alphaworks.ibm.com/tech/rsmb ) 
b> 進入對應的目錄,好比32位的Linux系統則應該進入linux_ia32目錄。 
c> 編輯配置文件broker_1883.cfg,配置以下: html

[html]   view plain  copy
 
  1. port 1883  
  2. max_inflight_messages 10  
  3. max_queued_messages 1000  

d> 運行./broker broker_1883.cfg,顯示以下: 
20120823 110454.039 CWNAN9999I Really Small Message Broker 
20120823 110454.039 CWNAN9997I Licensed Materials - Property of IBM 
20120823 110454.039 CWNAN9996I Copyright IBM Corp. 2007, 2010 All Rights Reserved 
20120823 110454.039 CWNAN9995I US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
20120823 110454.039 CWNAN0049I Configuration file name is broker_1883.cfg 
20120823 110454.040 CWNAN0053I Version 1.2.0, Aug 18 2010 17:03:35 
20120823 110454.040 CWNAN0054I Features included: bridge 
20120823 110454.040 CWNAN9993I Author: Ian Craggs (icraggs@uk.ibm.com) 
20120823 110454.040 CWNAN0014I MQTT protocol starting, listening on port 1883 
... ... 
這樣,推送服務的服務端就已經準備好了,監聽1883端口。 

三、推送客戶端準備 

a> 下載&解壓AndroidPushNotificationsDemo項目(下載地址: https://github.com/tokudu/AndroidPushNotificationsDemo ) 
b> 將該項目導入Eclipse中(File -> Export -> Existing Projects into Workspace) 
c> 修改PushService.java中的 MQTT_HOST 常量爲推送服務端的IP地址。 
d> 啓動Android模擬器,並安裝該項目。 

注意: 在新版本的Android SDK中可能會遇到如下錯誤。 
... ... 
08-23 02:28:44.184: W/dalvikvm(282): VFY: unable to find class referenced in signature (Lcom/ibm/mqtt/MqttPersistence;) 
08-23 02:28:44.194: I/dalvikvm(282): Failed resolving Lcom/tokudu/demo/PushService$MQTTConnection; interface 35 'Lcom/ibm/mqtt/MqttSimpleCallback;' 
08-23 02:28:44.194: W/dalvikvm(282): Link of class 'Lcom/tokudu/demo/PushService$MQTTConnection;' failed 
08-23 02:28:44.194: E/dalvikvm(282): Could not find class 'com.tokudu.demo.PushService$MQTTConnection', referenced from method com.tokudu.demo.PushService.connect 
08-23 02:28:44.194: W/dalvikvm(282): VFY: unable to resolve new-instance 42 (Lcom/tokudu/demo/PushService$MQTTConnection;) in Lcom/tokudu/demo/PushService; 
... ... 
08-23 02:28:44.404: E/AndroidRuntime(282): java.lang.VerifyError: com.tokudu.demo.PushService 
08-23 02:28:44.404: E/AndroidRuntime(282):     at com.tokudu.demo.PushActivity$1.onClick(PushActivity.java:32) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at android.view.View.performClick(View.java:2408) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at android.view.View$PerformClick.run(View.java:8816) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at android.os.Handler.handleCallback(Handler.java:587) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at android.os.Handler.dispatchMessage(Handler.java:92) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at android.os.Looper.loop(Looper.java:123) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at android.app.ActivityThread.main(ActivityThread.java:4627) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at java.lang.reflect.Method.invokeNative(Native Method) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at java.lang.reflect.Method.invoke(Method.java:521) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
08-23 02:28:44.404: E/AndroidRuntime(282):     at dalvik.system.NativeStart.main(Native Method) 
... ... 
緣由是發佈的時候沒有加入wmqtt.jar包,解決辦法以下: 
1> 在項目根目錄下建立libs目錄,並把wmqtt.jar包移入該目錄。 
2> 從新配置項目的Java Build Path(右鍵菜單中的Properties選項中)。 
3> 從新打包發佈便可。 

運行效果以下: 

 

點擊「Start Push Service」按鈕便可開啓推送服務。這時咱們能夠看到rsmb的服務日誌中打出如下提示: 
20120823 113742.297 CWNAN0033I Connection attempt to listener 1883 received from client tokudu/9774d56d682e549c on address 192.168.28.39:3345 
其中的「9774d56d682e549c」就是對應的客戶端ID號。 

四、發送服務準備 

a> 下載&解壓PHP版的發送服務端代碼send_mqtt.zip(下載地址: http://download.csdn.net/detail/shagoo/4520102 ) 
b> 修改etc/config.php中推送服務端的IP地址和端口號,即 MQTT_SERVER_HOST 和 MQTT_SERVER_POST 常量。 
c> 打開對應的URL地址,就能夠看到發送服務的界面,實際上就是向對應的推送客戶端推送消息。 

 

接着,咱們在該界面中填入客戶端ID(9774d56d682e549c)和推送消息(test)並點擊「Send Push Message」按鈕,服務端就能夠向客戶端推送消息了。咱們看到,客戶端上立馬就能夠收到剛剛推送的消息,以下圖。 

 

固然,以上方案還存在許多的不足,好比,若是客戶端沒有保持鏈接,發送的消息就會被丟棄。不過,咱們能夠利用MQTT協議開發出更強大的服務端來替代rsmb,更能夠加入隊列、緩存等功能進行優化,有興趣的朋友不妨試試。可參考開源項目 Mosquitto ( http://mosquitto.org/ ),相關內容咱們會在下一篇《 Mosquitto服務的安裝與使用 》中介紹。java

相關文章
相關標籤/搜索