android后台信息推送调研( 三 )


移动无线网络的特点
因为IP v4的IP量有限,运营商分配给手机终端的IP是运营商内网的IP,手机要连接,就需要通过运营商的网关做一个网络地址转换( ,NAT) 。简单的说运营商的网关需要维护一个外网IP、端口到内网IP、端口的对应关系,以确保内网的手机可以跟的服务器通讯 。

android后台信息推送调研

文章插图
NAT功能由图中的GGSN模块实现 。
大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰NAT表中的对应项,造成链路中断 。
平台上长连接的实现
为了不让NAT表失效,我们需要定时的发心跳,以刷新NAT表项,避免被淘汰 。
上定时运行任务常用的方法有2种,一种方法用Timer,另一种是 。
Timer
的Timer类可以用来计划需要循环执行的任务,Timer的问题是它需要用让CPU保持唤醒状态,这样会大量消耗手机电量,大大减短手机待机时间 。这种方式不能满足我们的需求 。
是系统封装的用于管理RTC的模块,RTC(Real Time Clock)是一个独立的硬件时钟,可以在CPU休眠时正常运行,在预设的时间到达时,通过中断唤醒CPU 。
这意味着,如果我们用来定时执行任务,CPU可以正常的休眠,只有在需要运行任务时醒来一段很短的时间 。极光推送的 SDK就是基于这种技术实现的 。
服务器设计
当有大量的手机终端需要与服务器维持长连接时,对服务器的设计会是一个很大的挑战 。
假设一台服务器维护10万个长连接,当有1000万用户量时,需要有多达100台的服务器来维护这些用户的长连接,这里还不算用于做备份的服务器,这将会是一个巨大的成本问题 。那就需要我们尽可能提高单台服务器接入用户的量,也就是业界已经讨论很久了的C10K问题 。
针对这个问题,我们专门成立了一个项目,命名为,顾名思义,我们的目标是单机维持200万个长连接 。最终我们采用了多消息循环、异步非阻塞的模型,在一台双核、24G内存的服务器上,实现峰值维持超过300万个长连接 。
后记
稳定维护长连接是推送平台的一个基础,极光推送团队将会在这方面长期投入,以保证用户能有效的节省电量、流量,同时数据能实时送达 。
附件二: 代码:
org..http..HTTP;
org.json.;
mon.;
com..gaea...;
..gaea..;
com..gaea.util.;
..;
.os.;
.os.;
.util.Log;
/**
* 运行通信的线程
*@ TCK-001
*@ 1.0
*/
@("")
final class{
void run() {
try {
while (true) {
if(!.get().()) {
;
sever =.get().();
if (null == sever ||sever.()) {
;
new (sever.()).start();
} catch ( e) {
Log.e("", "已经被回收");
/**
* 读取并解析
* @ TCK-001
* @ 1.0
*/
class{
;
android后台信息推送调研

文章插图
( ) {
this. = ;
void run() {
try {
=.get().(.(), HTTP.UTF_8, 1, false);
.close();
json = ();
if(json.("") == ..getId() &&..(json.(""))
&&.get().(.)) {
= ();
.("type", json.("type"));
.("data",json.("data").());
= ();
.();
.get().(null)..();
} catch ( e) {
Log.e("", "接收消息,解析json",e);
服务端代码:
/**
* 发送一个通信消息
* @param vo
* @
*/
( vo) {
try {
if (!(vo.getIp(), 2000)) { false;}
= new (vo.getIp(), vo.());// 创建对象,指定服务器端地址和端口号
= .();
= new (, .UTF_8);
out = new (, true);// 获取端的输出流