Android应用中消息推送完美方案分享

1.消息推送基础

消息推送,就是在互联网上通过定期传送用户需要的信息来减少信息过载的一项新技术。推送技术通过自动传送信息给用户,来减少用于网络上搜索的时间。它根据用户的兴趣来搜索、过滤信息,并将其定期推给用户,帮助用户高效率地发掘有价值的信息

当我们开发需要和服务器交互的移动应用时,基本上都需要和服务器进行交互,包括上传数据到服务器,同时从服务器上获取数据。

一般情况下,客户端与服务器之间通讯客户端是主动的,但这就存在一个问题就是一旦服务器数据有更新或者服务器要下发通知给客户端只能等客户端连接的时候才能实现。这种方式使消息失去了实时性。

如何使客户端能够实时的收到服务器的消息和通知,总体来说有两种方式,第一种是客户端使用Pull(拉)的方式,就是隔一段时间就去服务器上获取一下信息,看是否有更新的信息出现。第二种就是 服务器使用Push(推送)的方式,当服务器端有新信息了,则把最新的信息Push到客户端上。这样,客户端就能自动的接收到消息。 

  虽然Pull和Push两种方式都能实现获取服务器端更新信息的功能,但是明显来说Push方式比Pull方式更优越。因为Pull方式更费客户端的网络流量,更主要的是费电量,还需要我们的程序不停地去监测服务端的变化。  

2. 几种常见的解决方案实现原理

  1)轮询(Pull)方式:客户端定时向服务器发送询问消息,一旦服务器有变化则立即同步消息。

  2)SMS(Push)方式:通过拦截SMS消息并且解析消息内容来了解服务器的命令,但这种方式一般用户在经济上很难承受。

  3)持久连接(Push)方式:客户端和服务器之间建立长久连接,这样就可以实现消息的及时行和实时性。

3、消息推送解决方案概述

  A、C2DM云端推送方案

在Android手机平台上,Google提供了C2DM(Cloudto Device Messaging)服务。Android Cloud to Device Messaging (C2DM)是一个用来帮助开发者从服务器向Android应用程序发送数据的服务。该服务提供了一个简单的、轻量级的机制,允许服务器可以通知移动应用程序直接与服务器进行通信,以便于从服务器获取应用程序更新和用户数据。

该方案存在的主要问题是C2DM需要依赖于Google官方提供的C2DM服务器,由于国内的网络环境,这个服务经常不可用。

  B、MQTT协议实现Android推送

  采用MQTT协议实现Android推送功能也是一种解决方案。MQTT是一个轻量级的消息发布/订阅协议,它是实现基于手机客户端的消息推送服务器的理想解决方案。

  wmqtt.jar 是IBM提供的MQTT协议的实现。我们可以从这里(https://github.com/tokudu/AndroidPushNotificationsDemo)下载该项目的实例代码,并且可以找到一个采用PHP书写的服务器端实现(https://github.com/tokudu/PhpMQTTClient)。

  C、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地址下载它.

   D、XMPP协议实现Android推送

  Google官方的C2DM服务器底层也是采用XMPP协议进行的封装。XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息。

  androidpn是一个基于XMPP协议的java开源Android push notification实现。它包含了完整的客户端和服务器端。但也存在一些不足之处:

  1) 比如时间过长时,就再也收不到推送的信息了。

  2)性能上也不够稳定。

3)如果将消息从服务器上推送出去,就不再管理了,不管消息是否成功到达客户端手机上。

如果我们要使用androidpn,则还需要做大量的工作,需要理解XMPP协议、理解Androidpn的实现机制,需要调试内部存在的BUG。

  E、使用第三方平台

  目前国内、国外有一些推送平台可供使用,但是涉及到收费问题、保密问题、服务质量问题、扩展问题等等,又不得不是我们望而却步。

4、消息推送完美方案

      综合以上论述,在建立Android消息推送方面可谓方案多多,但每一款方案都有其优缺点。但无论如何,还是自己搭建一个推送平台是上策。因为你有、他有不如自己有。

         在搭建自有推送平台上建议使用《九日升Android消息推送组件》(http://www.bjjrs.net/product/13629681868537.html)。该组不仅可以拿来即用,并且还可以提供源码以便扩展,实现自己的特殊需求。

       A、推送原理

    九日升Android消息推送组件基于XMPP协议实现Android推送。XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息。

    九日升Android消息推送组件实现原理见下图:

           
                                                  图1-消息推送原理图

    九日升Android消息推送组件由服务器部分和客户端部分组成。每一部分都由XMPP协议组件和外部接口组件构成。XMPP协议组件负责服务器和Android客户端间的连接管理、消息通讯,外部接口组件负责接收应用系统、客户端应用的命令,向应用系统发送接收到的通知消息。

    九日升Android消息组件提供基于Tomcat的服务器应用和Android开发jar包。其中基于Tomcat的服务器应用直接在Tomcat上部署即可,Android开发jar包引入Android项目即可。

   B 集成方式

    1)、服务器部署

    九日升Android消息组件Tomcat的服务器应用直接部署在Tomcat中,端口号任意设定。

    2)、客户端jar包引用

    在Android项目中建立libs目录,然后将提供的Android开发jar包复制到该目录即可。见下图:

                                        

图2-jar包引入图

    3)、Android项目AndroidManifest.xml文件修改

  在该文件中增加以下权限:

     <uses-permission android:name="android.permission.READ_PHONE_STATE" />

     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

     <uses-permission android:name="android.permission.INTERNET" />

     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

     <uses-permission android:name="android.permission.VIBRATE" />

   在该文件中注册服务:

     <service android:enabled="true"

     android:name="com.bjjrs.server.NotificationService"

     android:label="NotificationService">

          <intent-filter>

             <action android:name="com.bjjrs.server.NotificationService" />

         </intent-filter>

    </service>

   至此,九日升Android消息组件集成工作完成。

    C、接口方式

    1)、服务器端接口采用基于http协议的访问方式,采用http协议从服务器中获取各种信息,实现通知消息的推送。

如使用以下方式和参数就可以实现各种用户消息的查询:

  http://localhost:8080/user.do?action=getAllUser&isOnline=&userID=&userType=&deptID=&deptName=&realName=

    使用如下方式就可以实现各种消息的推送:

    http://localhost:8080/notification.do?action=pushNoti&userNames=&title=&content=

    2)、Android客户端接口采用广播机制。

    消息接收:当XMPP协议组件接收到推送消息时,将按照一定格式广播该消息,通知客户端其他应用接收并处理该消息。

    消息发送:客户端应用需要向服务器或者其他客户端发送即时消息时,只需按一定格式广播该消息,XMPP组件就会自动接收该消息并发送到指定的其他客户端。

    D、优势特点

    1)、系统集成简单,无需复杂的设置。

    2)、Android客户端应用和九日升Android消息推送组件完全分离,通过接口相互调用,实现模块应用最优化。

    3)、客户端通讯机制采用广播方式,给客户端应用带来极大的灵活性和可扩展性,可以自由处理接收到的推送消息。

    4)、九日升Android消息推送组件在服务器端具备消息存储、消息重发、消息路由等功能,在客户端部分具备断线重连、、收到确认、阅读确认、消息发送、命令执行等功能,确保消息能够推送到客户端,同时也保证客户端能够收到、阅读消息。

   E、 应用范围

  九日升Android消息推送组件可在以下场景中使用:

    1)、用于消息推送。如:通知下达、应急指挥等。

    2)、用户及时消息交互。如在线聊天、工作情况交互等。

    3)、用于远程控制。如控制远程客户端的状态、数据上报等。

Android消息推送机制

1.推送方式基础知识:

当我们开发需要和服务器交互的应用程序时,基本上都需要获取服务器端的数据,比如《地震应急通》就需要及时获取服务器上最新的地震信息。要获取服务器上不定时更新的信息一般来说有两种方法,第一种是客户端使用Pull(拉)的方式,隔一段时间就去服务器上获取信息,看是否有更新的信息出现。第二种就是服务器使用Push(推送)的方式,当服务器端有新信息了,则把最新的信息Push到客户端上。 

虽然Pull和Push两种方式都能实现获取服务器端更新信息的功能,但是明显来说Push is better than
pull。因为Pull方式更费客户端的网络流量,更主要的是费电量。  

在开发Android和iPhone应用程序时,我们往往需要从服务器不定的向手机客户端即时推送各种通知消息,iPhone上已经有了比较简单的和完美的推送通知解决方案,我会在以后详细介绍IPhone中的解决方案,可是Android平台上实现起来却相对比较麻烦,最近利用几天的时间对
Android的推送通知服务进行初步的研究。在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服务器,由于国内的网络环境,这个服务经常不可用,如果想要很好的使用,我们的App
Server必须也在国外,这个恐怕不是每个开发者都能够实现的;
有了上述两个使用上的制约,导致我最终放弃了这个方案,不过我想利用另外一篇文章来详细的介绍C2DM的框架以及客户端和App
Server的相应设置方法,可以作为学习与参考之用。即然C2DM无法满足我们的要求,那么我们就需要自己来实现Android手机客户端与App
Server之间的通信协议,保证在App Server想向指定的Android设备发送消息时,Android设备能够及时的收到。

2. 几种常见的解决方案

1)轮询(Pull):应用程序应当阶段性的与服务器进行连接并查询是否有新的消息到达,你必须自己实现与服务器之间的通信,例如消息排队等。而且你还要考虑轮询的频率,如果太慢可能导致某些消息的延迟,如果太快,则会大量消耗网络带宽和电池。

2)SMS(Push):在Android平台上,你可以通过拦截SMS消息并且解析消息内容来了解服务器的意图。这是一个不错的想法,我就见过采用这个方案的应用程序。这个方案的好处是,可以实现完全的实时操作。但是问题是这个方案的成本相对比较高,你很难找到免费的短消息发送网关,关于这个方案的实现。

3)持久连接(Push):这个方案可以解决由轮询带来的性能问题,但是还是会消耗手机的电池。Apple的推送服务之所以工作的很好,是因为每一台手机仅仅保持一个与服务器之间的连接,事实上C2DM也是这么工作的。不过这个方案也存在不足,就是我们很难在手机上实现一个可靠的服务。

Android操作系统允许在低内存情况下杀死系统服务,所以你的通知服务很可能被操作系统Kill掉了。前两个方案存在明显的不足,第三个方案也有不足,不过我们可以通过良好的设计来弥补,以便于让该方案可以有效的工作。毕竟,我们要知道GMail,GTalk以及GoogleVoice都可以实现实时更新的。

3. MQTT协议实现Android推送

采用MQTT协议实现Android推送 MQTT是一个轻量级的消息发布/订阅协议,它是实现基于手机客户端的消息推送服务器的理想解决方案。
wmqtt.jar 是IBM提供的MQTT协议的实现。我们可以从这里下载该项目的实例代码,并且可以找到一个采用PHP书写的服务器端实现。

架构如下所示:


wmqtt.jar 是IBM提供的MQTT协议的实现。我们可以从如下站点下载它。你可以将该jar包加入你自己的Android应用程序中。

4.RSMB实现推送:

Really Small Message Broker (RSMB)
,他是一个简单的MQTT代理,同样由IBM提供。缺省打开1883端口,应用程序当中,它负责接收来自服务器的消息并将其转发给指定的移动设备。

SAM是一个针对MQTT写的PHP库。我们可以从这个下载它.

send_mqtt.php是一个通过POST接收消息并且通过SAM将消息发送给RSMB的PHP脚本。

Really Small Message Broker (RSMB)
,他是一个简单的MQTT代理,同样由IBM提供。缺省打开1883端口,应用程序当中,它负责接收来自服务器的消息并将其转发给指定的移动设备。

5. XMPP协议实现Android推送

这是我在项目中采用的方案。事实上Google官方的C2DM服务器底层也是采用XMPP协议进行的封装。
XMPP(可扩展通讯和表示协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线探测。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息。

androidpn是一个基于XMPP协议的java开源Android push
notification实现,我会在以后的博文中详细介绍androidpn。它包含了完整的客户端和服务器端。经过源代码研究我发现,该服务器端基本是在另外一个开源工程openfire基础上修改实现的,不过比较郁闷的是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协议我们还可以进一步的对协议进行扩展,实现更为完善的功能。采用这个方案,我们目前只能发送文字消息,不过对于推送来说一般足够了,因为我们不能指望通过推送得到所有的数据,一般情况下,利用推送只是告诉手机端服务器发生了某些改变,当客户端收到通知以后,应该主动到服务器获取最新的数据,这样才是推送服务的完整实现。

时间: 2024-08-03 05:40:27

Android应用中消息推送完美方案分享的相关文章

现代IM系统中消息推送和存储架构的实现

前言 IM全称是『Instant Messaging』,中文名是即时通讯.在这个高度信息化的移动互联网时代,生活中IM类产品已经成为必备品,比较有名的如钉钉.微信.QQ等以IM为核心功能的产品.当然目前微信已经成长为一个生态型产品,但其核心功能还是IM.还有一些非以IM系统为核心的应用,最典型的如一些在线游戏.社交应用,IM也是其重要的功能模块.可以说,带有社交属性的应用,IM功能一定是必不可少的. IM系统在互联网初期即存在,其基础技术架构在这十几年的发展中更新迭代多次,从早期的CS.P2P架

怎样使用android客户端的消息推送开源包androidpn。

问题描述 怎样使用android客户端的消息推送开源包androidpn. 下载了androidpn 的server和client 0.5.0的版本,具体怎么部署,客户端怎么实现,服务端怎么实现呢,最好有实际经验的朋友帮忙解答一下.非常感谢.

Android几种消息推送方案总结

首先看一张国内Top500 Android应用中它们用到的第三方推送以及所占数量: 现在总结下Android平台下几种推送方案的基本情况以及优缺点: 一.使用GCM(Google Cloude Messaging) Android自带的推送GCM可以帮助开发人员给他们的Android应用程序发送数据.它是一个轻量级的消息,告诉Android应用程序有新的数据要从服务器获取,或者它可能是一个消息,其中包含了4KB的payload data(像即时通讯这类应用程序可以直接使用该payload消息).

Android端新消息推送

问题描述 当退出软件时却未退出环信登录状态,那么:1.如何取消新消息的推送?2.当有新消息推送过来时,如何取消铃音提示?3.我只想在10:00--18:30这段时间内接收新消息推送,其余时间不接收新消息推送,该怎么做? 解决方案 public synchronized void onNewMsg(EMMessage message) {        if(EMChatManager.getInstance().isSlientMessage(message)){            retu

个推是移动消息推送技术服务商

个推现在每天向用户分发8亿条消息,但他们却觉得推送得太多了,未来的推送应该是"在合适的时间.合适的场景把合适的内容推送给合适的人".今天,个推在GMIC大会上发布了他们即将在6月面向所有开发者的个推2.0 Smart Push,希望帮助app摒弃打扰用户的盲目推送. 个推是移动(Android & iOS)消息推送技术服务商,服务的app包括新浪微博.去哪儿.招行.墨迹.唱吧.美图秀秀等.根据个推CEO方毅的介绍,个推目前在第三方推送服务的部署量上占了90%的市场份额,接入应用

APP消息推送到达率评估方案

近期社区里许多开发者问到了移动APP Android端的消息推送到达率的对比方案,正好近期看到了一篇CSDN的博文,介绍了作者所在公司总结的消息推送到达率的评估方案,比较合理,MARK一下,也供广大开发者参考. 原文地址如下:http://blog.csdn.net/asialiyazhou/article/details/60954636

Parse Server 支持 iOS 和安卓的消息推送

Parse Server 是前些天 Facebook 刚刚开源的兼容 Parse.com API 的服务器软件.目前该项目宣布支持 iOS 和 Android 平台的消息推送.可通过 PushAdapter 来实现. 使用方式: curl -X POST \ -H "X-Parse-Application-Id: YOUR_APP_ID" \ -H "X-Parse-Master-Key: YOUR_MASTER_KEY" \ -H "Content-Ty

Android中利用App实现消息推送机制的代码_Android

1.消息推送机制 服务器器端需要变被动为主动,通知客户一些开发商认为重要的信息,无论应用程序是否正在运行或者关闭. 我想到了一句话:don't call me,i will call you! qq今天在右下角弹出了一个对话框:"奥巴马宣布本拉登挂了...",正是如此. 自作聪明,就会带点小聪明,有人喜欢就有人讨厌. 2.独立进程 无论程序是否正在运行,我们都要能通知到客户,我们需要一个独立进程的后台服务. 我们需要一个独立进程的后台服务. 在androidmanifest.xml中注

Android中使用socket通信实现消息推送的方法详解_Android

原理最近用socket写了一个消息推送的demo,在这里和大家分享一下. 主要实现了:一台手机向另外一台手机发送消息,这两台手机可以随时自由发送文本消息进行通信,类似我们常用的QQ. 效果图: 原理:手机通过socket发送消息到服务器,服务器每接收到一条消息之后,都会把这条消息放进一个messageList里面,服务器会不停地检测messageList是否含有消息,如果有的话就会根据messageList里面item的数据,推送到相应的另一端手机上面. 下面简单画了一个图来说明这个原理: 演示