首页 > 其他分享 >Android实现推送方式解决方案 (转1)

Android实现推送方式解决方案 (转1)

时间:2023-05-10 10:31:50浏览次数:64  
标签:实现 解决方案 C2DM 服务器 Android 推送 客户端


Android实现推送方式解决方案


本文介绍在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操作过程图:


Android实现推送方式解决方案 (转1)_服务器

 

但是经过一番研究发现,这个服务存在很大的问题:  

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书写的服务器端实现

架构如下所示:


Android实现推送方式解决方案 (转1)_Android_02

 

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)以及在线探测。这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息。关于XMPP协议我在上篇博文中已经介绍,大家可以参考:javascript:void(0)

 

androidpn是一个基于XMPP协议的java开源Android push notification实现,我会在以后的博文中详细介绍androidpn。它包含了完整的客户端和服务器端。经过源代码研究我发现,该服务器端基本是在另外一个开源工程openfire基础上修改实现的,不过比较郁闷的是androidpn的文档是由韩语写的,所以整个研究过程基本都是读源码。

 

实现意图如下图所示:


Android实现推送方式解决方案 (转1)_移动开发_03

 

androidpn 客户端需要用到一个基于java的开源XMPP协议包asmack,这个包同样也是基于openfire下的另外一个开源项目smack,不过我们不需要 自己编译,可以直接把androidpn客户端里面的asmack.jar拿来使用。客户端利用asmack中提供的XMPPConnection类与服 务器建立持久连接,并通过该连接进行用户注册和登录认证,同样也是通过这条连接,接收服务器发送的通知。

 

androidpn服务器端也是java语言实现的,基于openfire开源工程,不过它的Web部分采用的是spring框架,这一点与 openfire是不同的。Androidpn服务器包含两个部分,一个是侦听在5222端口上的XMPP服务,负责与客户端的 XMPPConnection类进行通信,作用是用户注册和身份认证,并发送推送通知消息。另外一部分是Web服务器,采用一个轻量级的HTTP服务器, 负责接收用户的Web请求。服务器架构如下:

 


Android实现推送方式解决方案 (转1)_java_04

 

最上层包含四个组成部分,分别是SessionManager,Auth Manager,PresenceManager以及Notification Manager。SessionManager负责管理客户端与服务器之间的会话,Auth Manager负责客户端用户认证管理,Presence Manager负责管理客户端用户的登录状态,NotificationManager负责实现服务器向客户端推送消息功能。

 

这个解决方案的最大优势就是简单,我们不需要象C2DM那样依赖操作系统版本,也不会担心某一天Google服务器不可用。利用XMPP协议我们还可以进一步的对协议进行扩展,实现更为完善的功能。 采用这个方案,我们目前只能发送文字消息,不过对于推送来说一般足够了,因为我们不能指望通过推送得到所有的数据,一般情况下,利用推送只是告诉手机端服务器发生了某些改变,当客户端收到通知以后,应该主动到服务器获取最新的数据,这样才是推送服务的完整实现。 

 

至于详细使用过程,我们会在下个博文中再给大家介绍。

完毕。 

标签:实现,解决方案,C2DM,服务器,Android,推送,客户端
From: https://blog.51cto.com/u_16034393/6260653

相关文章

  • Android自定义Dialog(zhuang)
    Android自定义Dialog这段时间在做一个项目,需要使用到自定义Dialog,先在网上找了一下资料,发现还是有很多没有讲清楚的,在此给出一个Demo,一来可以方便广大码农,二来也可以方便自己,以备不时之需。。。先来一张图吧,很简单,只有一个Activity,当点击Button的时候就弹出这个自定义的Dialo......
  • git仓库过渡,同时向两个仓库推送代码
    公司部门被大佬收购,产品项目迁移新公司仓库,过渡期间产品上线流程继续使用原公司的,新公司部署新系统后通过域名重定向逐渐将用户引流到新系统上完成切换,最后关闭原公司系统及上线流程。过渡期间新功能代码需要保证两边git仓库里一致,即执行gitpush命令时同时往两个仓库里推送代码......
  • 计讯物联环保数采仪TS910在扬尘预警监测解决方案的应用
    方案背景随着我国经济高速发展和城市化进程的加速,城市建设工程规模不断扩大,工程施工给居住区、学校、医院等周边环境带来了巨大的影响,特别是扬尘污染带来的细颗粒物,严重危害到人体健康和大气环境质量。 因此,计讯物联以可持续发展为设计理念,践行国家“双碳”发展战略,实力打造稳......
  • Android logcat: Unexpected EOF! 解决办法
     【问题表现】无论使用控制台adb( adblogcat|grep"SilentPlayerManager")还是使用AndroidStudio的logcat,都提示: logcat:UnexpectedEOF!Thismeansthateitherthedeviceshutdown,logdcrashed,orthisinstanceoflogcatwasunabletoreadlogmessagesas......
  • Android Studio中使用断点调试程序
    1.设置断点在希望中断的位置左边label一下,设置一个断点。例如下方图片所示在ActivityResultRegistry类中的第147行设置了一个断点,以及在365行dispatchResult()方法处设置了一个断点。设置好断点后,可以在菜单栏依次点击Run->ViewBreakpoints查看所设置的全部的断点,并进行删减......
  • android.app.BackgroundServiceStartNotAllowedException
    ---------beginningofcrash05-0901:25:24.46521872187EAndroidRuntime:FATALEXCEPTION:main05-0901:25:24.46521872187EAndroidRuntime:Process:com.android.gallery3d,PID:218705-0901:25:24.46521872187EAndroidRuntime:java.lang.Runti......
  • Android TextView 设置超链接、关键字高亮等效果
    之前做TextView关键字高亮效果,使用的是Html.fromHtml(Stringsource)方法,然后通过TextView的setText(CharSequencetext)方法来显示后来测试此方法在部分手机上显示有问题,如Nexus4,华为P6等等。于是乎只能继续寻找别的解决办法了,在这里Mark一下。这里用到了SpannableString类......
  • 一站式统一返回值封装、异常处理、异常错误码解决方案—最强的Sping Boot接口优雅响应
    作者:京东物流 覃玉杰1.简介GracefulResponse是一个SpringBoot体系下的优雅响应处理器,提供一站式统一返回值封装、异常处理、异常错误码等功能。使用GracefulResponse进行web接口开发不仅可以节省大量的时间,还可以提高代码质量,使代码逻辑更清晰。强烈推荐你花3分钟学会它!......
  • Windows系列---【浏览器突然连不上网,报"ERR_PROXY_CONNECTION_FAILED"的解决方案】
    浏览器突然连不上网,报"ERR_PROXY_CONNECTION_FAILED"的解决方案1.问题电脑的浏览器里装的有梯子,突然有一天浏览器访问不了外网了,打开哪个网站都报"ERR_PROXY_CONNECTION_FAILED",但是微信可以正常使用。2.分析微信可以使用,显然是浏览器的问题,再看错误,明显是代理有问题。3.解......
  • java.lang.NullPointerException解决方案,以及发生的原因。
    其实解决方案,倒是挺简单的,eclipse的console里,报错的地方点一下,就知道在哪一行了。真正要注意的是怎么避免这种情况的发生。通常情况下,这种错,发生在取数据的过程,比方从数据库查询数据,亦或者说是,发生在数据传输的过程中。譬如1packagetest;23importjava.util.List;......