Android推送技术探索


推送方案介绍


    1、C2DM云端推送,Google出品
    C2DM提供了一个简单的、轻量级的机制,允许服务器可以通知移动应用程序直接与服务器进行通信,以便于从服务器获取应用程序更新和用户数据。但是依赖于Google官方提供的C2DM服务器,但在无法访问Google服务,另外国内系统制定化程度深,一些手机厂商阉割了这一模块,导致无法使用。
    2、使用GCM
    Android自带的推送GCM可以帮助开发人员给他们的Android应用程序发送数据。Google提供的服务、原生、简单,无需实现和部署服务端。要求Android 2.2以上,对于不少2.2以前的系统没法推送,另外还需要注册,绑定Google账号。和上面情况一样,有些手机厂商阉割了这一功能,无法使用。
    3、轮询
    基于Pull方式,应用程序隔固定时间主动与服务器进行连接并查询是否有新的。但是到达不及时,耗电,耗性能,占用服务器资源带宽。
    4、MQTT协议
    轻量级的消息发布/订阅协议,基于Push方式,是IBM提供的MQTT协议的实现,没有开源,开发复杂度很高,难度比较大。
    5、XMPP协议
    XMPP是一种基于XML的协议,它继承了在XML环境中灵活的发展性,有很强的可扩展性。包括上面讲的GCM服务器底层也是采用XMPP协议封装的。
    7、第三方SDK
    极光推送,友盟推送,小米推送,华为推送等等。


推送中的长链接


    要推送消息能够及时收到,就要要求客户端和服务端保持一个长链接,不轻易断开,就算断开,也能够及时的链接起来。当客户端在与服务器建立了TCP连接之后,就可以进行通信了,他的链接过程涉及到TCP协议的三次握手过程,接下来看看TCP协议的三次握手和四次分手过程。


TCP的三次握手



1、客户端发送一个TCP的SYN标志位置1,并且指明连接服务器的端口号。
2、服务器接收到了之后就会把当前服务器的一个状态码+1,向客户端发出应答请求,此时服务器的状态改变,准备建立连接。
3、客户端接收到服务器发过来的SYN包时,向服务器发送一个确认包。当服务端收到之后校验正常,就可以见了TCP链接了。


TCP的四次挥手




1、客户端向服务端发送断开带有FIN标记请求数据包。
2、服务端收到客户端发送的FIN请求之后,可能数据还没有传完毕,就向客户端发出确认信号ACK。
3、当服务端数据处理完成之后,向客户端发送FIN,标识服务端数据处理完毕,可以断开了。
4、客户端收到FIN释放报文请求后,确认断开,然后就断开TCP链接。


    经过三次握手过程,客户端和服务端建立起长链接,但是这种连接是不稳定的,容易受设备,网络,内存等因素影响,导致断开这时候我们需要将他们再次建立链接,以保证信息及时的push到客户端,这时候需要用到心跳包。


长链接中的心跳包


    心跳包,即判断app是否还活着,是否还有心跳,如果没有心跳,服务器就会断开,节省服务器资源。在心跳包中客户端往往设定一个时间,定期的向服务器发送心跳通知,告诉服务器还活着,来保持客户端和服务端的长链接。所以这个心跳包的时间间隔应该尽量的长,同时保证链接不断开。


心跳包的时间间隔


    要确定心跳包的时间间隔,先来了解下NAT超时。很多时候我们移动网络或者WiFi时候,因为IPv4地址不足,我们的设备可能会处在一个NAT设备的后面,这时候NAT设备会给我们提供一个虚拟的网络IP,供我们连接网络使用,但是过段时间我们仅仅是建立连接,却没有通信,这时候NAT设备会淘汰掉这个虚拟的IP,把它回收掉。造成链路中断,导致连接超时。所以客户端自动测算NAT超时时间,来动态调整心跳间隔,是保持长链接的一个关键。


    如果心跳包设置的时间过短,会频繁的唤醒设备,甚至导致设备无法休眠,会消耗大量的电量;如果时间设置的过长,NAT超时,TCP长连接链路就会中断,Server就无法发送Push给手机,只能等到客户端下次心跳失败后,重建连接才能取到消息。因此需要找到一个NAT超时的临界点,让心跳包的时间间隔略小于这个临界点,才能充分发挥心跳包的优势,最大限度的节省资源。下面列出一些常见的NAT超时时间统计:


    中国移动3G和2G        5分钟
    中国联通2G                5分钟
    中国电信3G                大于28分钟


    其他心跳包固定参数或者动态心跳计算方法请参考:http://www.52im.net/thread-209-1-1.html


设备休眠


    Android设备开启后,过一段时间如果没有操做,手机会变暗,最终息屏,这时候CPU会停止运行,进如休眠状态。如何定时发送心跳包到建立起长链接呢?在定时发送中,使用Timer计时器或者Handler,Timer或者Handler等会不断的循环发送定时任务,在息屏状态下由于CPU休眠,可能会导致心跳包中断,掉线。


    在Android系统中有两个处理器,一个叫Application Processor(AP),一个叫Baseband Processor(BP)。AP是ARM架构的处理器,用于运行Linux+Android系统;BP用于运行实时操作系统(RTOS),通讯协议栈运行于BP的RTOS之上。非通话时间,BP的能耗基本上在5mA左右,而AP只要处于非休眠状态,能耗至少在50mA以上,执行图形运算时会更高。另外LCD工作时功耗在100mA左右,WIFI也在100mA左右。一般手机待机时,AP、LCD、WIFI均进入休眠状态,这时Android中应用程序的代码也会停止执行。


    Android为了确保应用程序中关键代码的正确执行,提供了Wake Lock的API,使得应用程序有权限通过代码阻止AP进入休眠状态。但是开发者为了保持长链接而滥用这个API,阻止手机休眠,会非常的耗电,违反了这个API的设置初衷。


    在待机状态,AP收不到消息推送怎么办呢?这里还有BP存在,因为通讯协议栈运行于BP的RTOS之上,他的耗电量是非常少的,可以借助于BP进行处理,一旦收到数据包,BP会将AP唤醒,唤醒的时间足够AP执行代码完成对收到的数据包的处理过程。那么客户端如何借助于BP向服务端发送心跳包,Android提供的AlarmManager就是来解决这个问题的,他能够唤醒起来AP的执行程序,而WakeLock来保护心跳包断开时候的重连过程,当连接好之后,及时释放WakeLock。


    AlarmManager是Android 系统封装的用于管理RTC的模块,RTC(Real Time Clock)是一个独立的硬件时钟,可以在CPU休眠时正常运行,在预设的时间到达时,通过中断唤醒CPU。AlarmManager不受手机状态的影响,基于系统的AlarmService来执行,虽然系统让手机息屏了,但是系统有些优先级很高的程序还是在执行的,例如闹钟,利用AlarmService可以定时启动自己的程序,只有在执行任务时,才唤醒CPU,这个过程是很短时间的,所以基本上不怎么耗费电量。他提供对系统闹钟服务的访问接口,使用它既可以指定单次执行的定时任务,也可以指定重复运行的任务。当闹钟指定触发时间到达时,实际上是系统发出为这个闹钟注册的广播,因此我们需要定义一个广播,来接收这个事件,在里面实现心跳包的时间设定,与服务端进行交互。


参考:
http://www.cnblogs.com/kobe8/p/3819305.html
http://www.52im.net/thread-209-1-1.html




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值