http://blog.csdn.net/axi295309066/article/details/53180628
版权声明:本文为博主原创文章,未经博主允许不得转载。
消息推送,即时通信,目的:想办法让服务器能够及时的通知客户端
消息推送最简单的方法就是使用第三方的,比如现在使用比较多的是小米推送、极光推送,消息推送的技术原理是:移动无线网络长连接
实现方案
1、轮询
客户端每隔一定的时候就向服务器发出请求,获得最新的信息。特点:
- 如果用在最新新闻通知上,那么效率就比较低了。
- 技术简单,好现实。
应用场景:当服务器端的数据以固定的频率更新,比如 股票行情。
2、发短信
特点:效率高,最及时,同时,费用也是最高的。
应用场景:比较土毫的做法,不差钱。
3、使用第三方的开源项目
AndroidPN ( Android push notify)
4、使用第三方的API实现推送功能
小米推送,百度推送、极光推送、个推、微信推送
实现方式3和4原理上都属于消息推送。
消息推送 的实现原理:Socket长联接 + 心跳桢
XMPP 网络上开源的,用于网络聊天的网络协议
asmack.jar jar包是对xmpp协议的实现
推送原理
- xmpp 是一种基于TCP/IP的协议, 这种协议更适合消息发送
- socket 套接字, 发送和接收网络请求
- 长连接 keep-alive, 服务器基于长连接找到设备,发送消息
- 心跳包 , 客户端会定时(30秒一次)向服务器发送一段极短的数据,作为心跳包, 服务器定时收到心跳,证明客户端或者,才会发消息.否则将消息保存起来,等客户端活了之后(重新连接),重新发送.
客户端轮询(客户端定时主动拉取数据), 浪费流量, 浪费性能
谷歌推送服务(不能用,被墙了)
移动互联网络的现状
因为手机平台本身、电量、网络流量的限制,移动互联网应用在设计上跟传统PC 上的应用很大不一样,需要根据手机本身的特点,尽量的节省电量和流量,同时又要尽可能的保证数据能及时到达客户端。为了解决数据同步的问题,在手机平台上,常用的方法有2种。
一种是定时去服务器上查询数据,也叫Polling,还有一种手机跟服务器之间维护一个TCP 长连接,当服务器有数据时,实时推送到客户端,也就是我们说的Push。从耗费的电量、流量和数据送达的及时性来说,Push 都会有明显的优势,但Push 的实现和维护成本相对较高。在移动无线网络下维护长连接,相对也有一些技术上的难度
移动无线网络的特点
因为IP v4 的IP 量有限,运营商分配给手机终端的IP 是运营商内网的IP,手机要连接Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网IP、端口到内网IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯。
对于大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰NAT 表中的对应项,造成链路中断。
Android 平台上长连接的实现
为了不让NAT 表失效,我们需要定时的发心跳,以刷新NAT 表项,避免被淘汰。Android 上定时运行任务常用的方法有2种,一种方法用Timer,另一种是AlarmManager。
Timer
Android 的Timer 类可以用来计划需要循环执行的任务,Timer 的问题是它需要用WakeLock 让CPU 保持唤醒状态,这样会大量消耗手机电量,大大减短手机待机时间。这种方式不能满足我们的需求。
AlarmManager
AlarmManager 是Android 系统封装的用于管理RTC 的模块,RTC (Real Time Clock) 是一个独立的硬件时钟,可以在CPU 休眠时正常运行,在预设的时间到达时,通过中断唤醒CPU。这意味着,如果我们用AlarmManager 来定时执行任务,CPU 可以正常的休眠,只有在需要运行任务时醒来一段很短的时间。极光推送的Android SDK 就是基于这种技术实现的。
服务器设计
当有大量的手机终端需要与服务器维持长连接时,对服务器的设计会是一个很大的挑战。假设一台服务器维护10万个长连接,当有1000万用户量时,需 要有多达100台的服务器来维护这些用户的长连接,这里还不算用于做备份的服务器,这将会是一个巨大的成本问题。那就需要我们尽可能提高单台服务器接入用 户的量,也就是业界已经讨论很久了的C10K 问题。
上面只是针对极光推送来说,下面是具体的消息推送的一般有的方式:
通过SMS进行服务器端和客户端的交流通信
在Android平台上,你可以通过拦截SMS消息并且解析消息内容来了解服务器的意图,可以实现完全的实时操作。但是问题是这个方案的成本相对比较高,且依赖于运营商
循环主动定时获取
这种方法需要客户端来做一个定时或者周期性的访问服务器端接口,以获得最新的消息。轮询的频率太慢可能导致某些消息的延迟,太快则会大量消耗网络带宽和电池
持久连接
这个方案可以解决由轮询带来的性能问题,但是还是会消耗手机的电池。我们需要开一个服务来保持和服务器端的持久连接(苹果就和谷歌的C2DM是这种 机制)。但是对于Android系统,当系统可用资源较低,系统会强制关闭我们的服务或者是应用,这种情况下连接会强制中断。(Apple的推送服务之所 以工作的很好,是因为每一台手机仅仅保持一个与服务器之间的连接,事实上C2DM也是这么工作的。即所有的推送服务都是经由一个代理服务器完成的,这种情 况下只需要和一台服务器保持持久连接即可。C2DM=Cloud to Device Messaging)。
相比之下第三种还是最可行的。为软件编写系统服务或开机启动功能;或者如果系统资源较低,服务被关闭后可以在onDestroy ()方法里面再重启该服务,进而实现持久连接的方式。
C2DM内置于Android的2.2系统上,无法兼容老的1.6到2.1系统;且依赖于Google官方提供的C2DM服务器,由于国内的网络环境,这个服务经常不可用。
建立在TCP协议之上的XMPP协议,不仅可提供可这种持久连接的功能,能实现服务器和客户机的双工通信,还能不依赖与系统版本和google服务器的限制,提供了比较好的解决方案。
小米消息推送服务
目前用的最多的,也是最稳定消息推送服务,http://dev.xiaomi.com/console/appservice/push.html