如何实现android与服务器的长连接

问一个问题:这个功能必须涉及客户端和服务器,那么客户端如何与服务器实时通信?

问题分析:这个功能其实就是数据同步,同时需要考虑手机本身、电量、网络流量等限制因素,所以移动端通常有两种解决方案:

1.一种是定期去服务器查询数据,通常使用HTTP协议访问web服务器,这种方式称为轮询;

2.另一种方式是在移动终端和服务器之间建立长连接,使用XMPP长连接,这种方式称为Push。(根据我的理解,当客户端实现时:

while(true) {

请求(超时);

请求(超时);

}

客户端发送一个“长”请求。如果服务器发送消息或超时,客户端将断开请求并建立一个长请求。

)

Push在功耗、流量、数据延迟等方面优势明显。但是使用推送的缺点是:

对于客户端来说,实现和维护相对昂贵,开发一些技术来维持移动无线网络下的长连接相对困难。

对于服务器:如何实现多核并发、cpu作业调度、大量长连接并发维护等技术,仍存在开发难点。

在说推送方案的原理之前,我们先来了解一下移动无线网络的特点。

移动无线网络的特征:

因为IP v4中的IP量是有限的,运营商分配给手机终端的IP就是运营商内网的IP。如果手机要连接互联网,需要通过运营商的网关做一个网络地址转换(NAT)。简单来说,运营商的网关需要维护外网ip、端口到内网IP、端口的对应关系,以保证内网的手机能够与互联网服务器进行通信。

示意图如下:

GGSN(网关GPRS支持节点网关GPRS支持节点)模块实现NAT功能。

因为大部分移动无线网络运营商都在努力降低网关的NAT映射表的负载,如果发现链路中有一段时间没有数据通信,就会删除相应的表,导致链路中断。关于NAT的作用和原理,请看我的另一篇博文:我用UDP(TCP)穿越局域网和NAT穿透的经验。

Android平台下Push长连接的实现:

由于我们知道我们的移动终端必须通过运营商的网关与互联网进行通信,为了防止NAT映射表失效,我们需要定期向互联网发送数据,因为仅仅为了防止NAT映射表失效,我们只需要发送长度为0的数据。

此时,将使用计时器。在android系统上,通常有两种计时器:

1 . Java . util . time

2.android.app.AlarmManager

分析:

定时器:可以根据日程或时间段执行相关任务。但是Timer需要WakeLock让CPU保持清醒来保证任务的执行,这样会消耗很多流量。CPU休眠时,无法唤醒执行任务,显然不适合移动终端。

AlarmManager:AlarmManager类属于android系统封装的管理类,用于管理RTC模块。这里涉及到RTC模块。要想更好地理解它们之间的区别,就必须了解它们之间真正的区别。

RTC(实时时钟)实时闹钟在嵌入式系统中,RTC通常用于提供可靠的系统时间,包括小时、分钟、日和月。而且要求系统在关机状态下能正常工作(一般由备用电池供电),其外围不需要太多辅助电路。通常情况下,它只需要一个高精度32.768KHz晶体以及电阻和电容。(如果你对这方面感兴趣,可以自己查阅相关资料,所以这里有个大概的思路。)

好吧,让我们回到正题。所以AlarmManager也叫全局定时器闹钟。这意味着当我使用AlarmManager定时执行任务时,CPU可以正常睡眠,只有在我执行任务时,才会唤醒CPU。这个过程很短。

下面简单解释一下它的用法:

1.类似于定时器功能:

//获取闹钟管理器

ALARM manager am =(ALARM manager)getsystem SERVICE(ALARM _ SERVICE);

//设置任务执行计划

am.setRepeating(AlarmManager。ELAPSED_REALTIME,firstTime,5*1000,发件人);//从第一次开始执行,之后每隔5秒执行一次。

2.实现全局计时功能:

//获取闹钟管理器

ALARM manager am =(ALARM manager)getsystem SERVICE(ALARM _ SERVICE);

//设置任务执行计划

am.setRepeating(AlarmManager。ELAPSED_REALTIME_WAKEUP,第一次,5*1000,发件人);//从第一次开始执行,之后每隔5秒执行一次。

结论:android客户端使用Push Push时,要使用AlarmManager实现心跳功能,这样才能真正实现长连接。

服务器端的实现:

在服务器端,可以用很多语言实现,比如C/C++、java、Erlang等等,比如Aurora Push (C开发)、openfire(java开发)等等。

最近看了极光推送的介绍和原理。我来说说他们遇到了什么问题,用了什么技术或者解决方案。

当大量的移动终端需要与服务器保持长时间的连接时,服务器的设计将是一个巨大的挑战。

假设一台服务器维护65438+百万长连接,当有10万用户时,需要多达100台服务器来维护这些用户的长连接,还不算用于备份的服务器,这将是一个巨大的成本问题。那么我们就需要尽可能的增加单个服务器的访问用户数,这就是业界讨论了很久的C10K的问题。

C2000K

为了解决这个问题,他们建立了一个名为C2000K的项目,顾名思义,他们的目标是在单台机器上保持200万个长连接。最终,他们采用了多消息周期、异步无阻塞的模式,在24G内存的双核服务器上实现了超过300万长连接的峰值。

最终总结:

因为最近用java做了一个PC端、服务器端、安卓端的即时通讯系统(说白了就是希望以后能有不同的功能)。我的原则是用别人的原则,自己去实现,这样可以更好的理解一些框架。所以,估算的难点在于通信和服务器的开发,必须深刻理解多消息循环和异步无阻塞模型。之后我会发表关于这方面的实现。

现在的安卓平台上,已经不是安卓单机游戏的天下了(我不是说单机游戏没有未来)。如今,整个IT系统是由蓬勃发展的互联网支撑的。所以,要成为安卓应用开发的专家,就要朝着安卓、硬件、云服务的体系发展。