PiYuqing 2013-10-11
当我们开发需要与服务器交互的应用程序时,基本上都需要获取服务器端的数据。要获取服务器上不定时更新的信息,一般来说有两种方法:第一种是客户端使用pull(拉)的方式,隔一段时间就去服务器上获取一下信息,看是否有更新的信息出现;第二种就是服务器使用push(推送)的方式,当服务器端有更新,则将最新的信息push到客户端上,如此以来,客户端就能自动地接收到消息。
虽然pull和push两种方式都能实现获取服务器端数据更新的功能,但pull方式的弊端很明显:费流量、费电,需要我们的程序不停地去监测服务器端的更新。
首先可以来了解一下iOS和Android平台的推送机制:
iOS 系统的推送(APNS,即 Apple Push Notification Service)依托一个或几个系统常驻进程运作,是全局的(接管所有应用的消息推送),所以可看作是独立于应用之外,而且是设备和苹果服务器之间的通讯,而非应用的提供商服务器。比如腾讯 QQ 的服务器(Provider)会给苹果公司对应的服务器(APNs)发出通知,然后再中转传送到你的设备(Devices)之上。当你接收到通知,打开应用,才开始从腾讯服务器接收数据,跟你之前看到通知里内容一样,但却是经由两个不同的通道而来。
Android的推送有两种形式,一种是后台Service,一种是GCM
不过这里要指出的是,Android的这种形式和传统电脑还是有区别的,电脑的后台是保持程序进程在后台运行,而Android是在程序后台Service区域添加一个新的程序专门接收数据。
要说的话,Android的后台推送机制更加复杂,但是因为可操控部分更多,加上GCM是在2.X之后才加上的而且有可能在系统中并不存在,所以很多软件都是使用Service这种形式。
本质上,APNs 与 GCM 是类似的技术实现原理:即系统层有一个常驻的 TCP 长连接,一直保持的长连接,即使手机休眠的时候也在保持的长连接。这里对于大部分人来说,最不理解的就是,休眠时候都保持在那里的 TCP 长连接,不会耗电很厉害么?
答案是:不会。这是手机的设计来做到的。TCP长连接有个心跳的时间,在国外可以很长比如30分钟,在国内则因为网络环境复杂一般10分钟。客户端发起的心跳,会短暂地消耗手机电能,但在这个心跳间隔期间,则消耗电能是很少的。当在心跳期间服务器端有推送信息过来时,客户端可以收到并做处理。
这里有篇文章以 Android 为例做原理解释:
http://blog.jpush.cn/index.php/jpush_wireless_push_principle/
极光推送技术原理:无线网络长连接
再说 APNs 的设计成功处。
iOS 为了真正地为用户体验负责,不允许应用在后台活动。有了这个限制,但是对于终端设备,应用又是有必要“通知”到达用户的,随时与用户主动沟通起来的(典型的如聊天应用)。
这就是 APNs 的逻辑所在:iOS 自己做个长驻后台保持连接。所有应用,有必要(申请)并且被允许(用户可以改设置)的话,可以通过 APNs 中转到达用户。
Android 因为后台可以长驻,尤其是国内的 Android 的手机上 Google自家的推送服务 GCM 处于基本不可用的状态。所以,各App各显神通。聊天类应用的话,大多数直接借用 XMPP 规范里的一些成果。少量如微信有IM底子的,自己开发协议。这些在实现原理上与 APNs / GCM 没有本质的区别,但有一定的技术门槛。而大多数普遍应用,要使用推送的话,则使用轮询的方式简单实现。
其实,国外如 Urban Airship 自己实现了 Android 上的第三方提供的推送平台。国内如极光推送也实现了第三方的推送平台(技术与微信、GCM、APNs类似)。理论上,如果一个 Android 设备上多款应用都使用极光推送这种第三方推送平台的话,也可以如 APNs 一样达到节省电量、流量消耗的效果。
另可参考Android实现推送方式解决方案
http://www.cnblogs.com/hanyonglu/archive/2012/03/04/2378971.html