基于安卓系统的保持UDP长连接的方法与流程

文档序号:15649153发布日期:2018-10-12 22:57阅读:984来源:国知局

本发明涉及通信领域,尤其是一种在安卓系统进入深度休眠后依旧能保持udp长连接的方法。



背景技术:

绝大多数使用移动终端(掌上计算机、移动电话、智能电话、多媒体电话、便携媒体播放器、gps单元、移动游戏系统等)的用户,一般都会安装从服务器接收通知消息的应用,也就是服务器会推送消息到移动终端上。

目前的终端设备与服务器进行连接时,一般都要通过中间的nat设备进行中转。服务器与终端进行通信时,需要首先建立连接通道,如果在每次需要通信之前都需首先建立该连接通道,较为耗费时间。因此,在无数据传输时如何维持服务器与终端之间的连接通道就成了需要解决的问题。在现有技术中,一般是通过终端设备向服务周期发送心跳包来维持该连接通道。该方案的缺点是:当终端设备处于深度休眠模式,系统的定时器也同时被休眠,因此依靠定时器的心跳包就起不到维持网络连接的作用,无法做到实时响应。

应用终端设备在安卓6.0版本以上,对电源管理机制做了大量优化,如果终端设备在非移动或充电状态下,系统则会进入深度休眠模式,市面上大部分的apk软件都会因为这个模式而不能及时响应信息,尤其是实时对讲应用更是无法使用。

此外,现有应用安卓系统的终端一般为多核cpu,为了充分利用多核cpu(记为m核,例如4核、8核等等),理想情况下,同时有m个工作进程在同时工作处理请求。于是在处理数据时,需要初始化m个绑定相同端口,相同ip地址(so_reuseaddr、so_reuseport)的udpsocket,接下来就靠内核的查找算法来达到client请求的负载均衡了。由于内核查找算法是固定的,于是,无形中所有的client被划分为m类:类型1的所有client请求全部被路由到工作进程1的udpsocket由工作进程1来处理,同样类型2的client的请求也全部被工作进程2来处理,其他以此类推。由此可见,现有的安卓系统在应用udp连接时很容易造成短时间的负载极端不均衡。

一般情况下,如果一个udp包能够标识一个请求,那么简单的解决方案是每个udpsocketn的工作进程n,自行fork出多个子进程来处理类型n的client的请求。这样每个子进程都直接recvfrom就可以了,拿到udp请求包就处理,拿不到就阻塞。然而,在实际发包过程中,常常是一个请求需要多个udp包来标识,此种情况下,在处理数据时,就需要将同一个client的所有udp包都路由到同一个工作子进程。此时,使得短时间的负载极端不均衡的情形更加加剧。



技术实现要素:

因此,针对上述问题,本发明提出一种基于安卓系统的保持udp长连接的方法,使其在安卓系统休眠后依旧能保持udp长连接,且不会耗费大量的电量或者流量成本,以解决现有技术之不足。

为了解决上述技术问题,本发明所采用的技术方案是,一种基于安卓系统的保持udp长连接的方法,应用于服务器,所述服务器通过数据传输网络与终端连接,该方法包括:

预先定制适用于终端的apk,该apk包括master进程、fork进程和休眠通知进程;master进程用于监听udpsocket的可读事件,当master进程监听到可读事件,从已连接的套接口上接收数据包;解析接收到的数据包,并判断该数据包是否来自于新地址的udp包,如果是,则fork进程创建一个新的子进程来处理该udp包;如果不是,则由地址映射表获取对应的原进程来处理该udp包;如果master进程在预设时间未监听到可读事件,则由休眠通知进程向服务器发送数据包通知该终端进入休眠,同时该终端进入休眠状态;

服务器接收到休眠通知进程的数据包后,间隔预设时间向终端的apk发送反向心跳包;其中,所述反向心跳包是用户数据包协议udp数据包;

apk接收服务器发来的反向心跳包,以维持udp链路。

进一步的,为保证udp长连接的可靠性,当终端的apk判断其处于非休眠状态时,终端的apk间隔预设时间向服务器发送心跳包以维持udp链路;其中,所述心跳包是用户数据包协议udp数据包。

现有技术中服务器为了探知终端是否休眠,需要额外一个进程来轮询各个终端,以判断是否处于休眠状态;本申请针对终端,采用上述终端主动向服务器发送休眠通知的方案,不仅提高了终端和服务器的连接策略转换速度,而且在预设时间未监听到可读事件时,自动使终端进入休眠状态,相比现有需要手动按下按钮而使终端进入休眠状态的方案,不仅更具有用户体验感,而且还大大降低了终端的功耗。此外,通过终端和服务器双向发送心跳包和反向心跳包,保证了无论终端是否处于休眠状态,均可保证udp的长连接。

进一步的,如果master进程监听到可读事件,从已连接的套接口上接收到的数据包是来自于新地址的udp包,则由工作进程表worker_list中查询是否已为该新地址创建了对应的worker子进程;如果没有查找到,则由fork进程创建一个新的子进程来处理该udp包,并将该新地址的信息记录到worker_list中。

现有的安卓系统进入深度休眠后,整个系统的定时器也都被冻结,因此让apk休眠一段时候后通过定时器唤醒系统发送udp心跳保持udp链路长连接的方式是不可行的。现有技术中,通过阻止系统进入休眠的方式,让udp处于长连接状态,但此种方式带来了待机功耗问题,大大缩短了终端的使用时长。在一些定制化比较深的机型中(如:华为、oppo、vivo等手机),待机一段时间后,系统将会强制回收这些高耗电应用。本申请采用了通过服务器定期往apk端发送反向心跳包以及终端定期向服务器发送心跳包的方式,来维持udp链路,不仅无需耗费大量的电量及流量成本,而且还能保证udp链路的可靠性。此种方式可广泛应用于有实时消息推送机制的应用,如即时消息、实时对讲等应用。

具体实施方式

下面详细描述本发明的实施例,所述实施例仅用于解释本发明,而不能理解为对本发明的限制。

现有的安卓系统进入深度休眠后,整个系统的定时器也都被冻结,因此让apk休眠一段时候后通过定时器唤醒系统发送udp心跳保持udp链路长连接的方式是不可行的。现有技术中,通过阻止系统进入休眠的方式,让udp处于长连接状态,但此种方式带来了待机功耗问题,大大缩短了手机的使用时长。在一些定制化比较深的机型中(如:华为、oppo、vivo等手机),待机一段时间后,系统将会强制回收这些高耗电应用。本申请真是为了解决上述问题而提出的。

具体的,本发明的一种保持udp长连接的方法,应用于服务器,所述服务器通过数据传输网络与终端连接,该方法思路是:当都是类型n的多个client请求udp数据包到来的时候,不同类型client的数据包路由问题交给内核,此时,建立一个master进程来监听udpsocket的可读事件,master进程监听到可读事件,就采用msg_peek选项来recvfrom数据包,如果发现是新的endpoit(ip、port)client的udp包,那么就fork一个新的进行来处理该endpoit的请求,具体包括如下过程:

过程1:预先定制适用于终端的apk,该apk包括用于监听udpsocket的可读事件的master进程、根据master进程的监听结果进行创建新的子进程的fork进程和用于向服务器通知终端进入休眠的休眠通知进程;

master进程监听udp_socket_fd的可读事件:pfd.fd=udp_socket_fd;pfd.events=pollin;poll(pfd,1,-1);

过程2:如果master进程监听到可读事件,pfd.revents&pollin为true。则探测一下到来的udp包是否是新的client的udp包:recvfrom(pfd.fd,buf,maxsize,msg_peek,(structsockaddr)pclientaddr,&addrlen);查找一下worker_list是否为该client创建过worker子进程了。如果没有查找到,fork进程就创建一个新的子进程来处理该请求,并将该client信息记录到worker_list中。如果查找到,则返回过程1;

此外,每个worker子进程,保存自己需要处理的client信息pclientaddr。worker子进程同样也监听udp_socket_fd的可读事件。poll(pfd,1,-1);当可读事件到来,pfd.revents&pollin为true。探测一下到来的udp包是否是本进程需要处理的client的udp包:recvfrom(pfd.fd,buf,maxsize,msg_peek,(structsockaddr)pclientaddr_2,&addrlen);比较一下pclientaddr和pclientaddr_2是否一致;

过程3:如果master进程在预设时间未监听到可读事件,则由休眠通知进程向服务器发送数据包通知该终端进入休眠,同时该终端进入休眠状态;

过程4:服务器接收到休眠通知进程的数据包后,间隔预设时间向终端的apk发送反向心跳包;其中,所述反向心跳包是用户数据包协议udp数据包;

过程5:apk接收服务器发来的反向心跳包,以维持udp链路。

为保证udp长连接的可靠性,当终端的apk判断其处于非休眠状态时,终端的apk间隔预设时间向服务器发送心跳包以维持udp链路;其中,所述心跳包是用户数据包协议udp数据包。

上述过程2中,当master进程监听到可读事件,接收到udp包时,所有的worker子进程均被唤醒,而反应最快的worker子进程能够取出udp包来处理,同时到来的数据包只能排队被取出。而更为严重的是,由于recvfrom的排他唤醒,很有可能会造成死锁。考虑下面一个场景:假设有worker1、worker2、worker3、和master共四个进程都阻塞在poll调用上,client1的一个新的udp包过来,这个时候,四个进程会被同时唤醒,worker1比较速度,赶在其他进程前将upd包取走了(worker1可以处理client1的udp包),于是其他三个进程的recvfrom扑空,它们worker2、worker3、和master按序全部阻塞在recvfrom上睡眠(worker2、worker3排在master前面先睡眠的)。这个时候,一个新client4的udp包packet4到来,(由于recvfrom的排他唤醒)这个时候只有worker2会从recvfrom的睡眠中醒来,然而worker而却不能处理该请求udp包。如果没有新udp包到来,那么packet4一直留在内核中,死锁了。之所以recv是排他的,是为了避免多个进程处理同一个数据包。因此,为了避免此种情况的发生,每个worker子进程保存自己需要处理的client信息,且实时监听可读事件;当从已连接的套接口上接收到数据包后,首先对该数据包进行解析,判断该数据包是否标识了一个独立的请求,如果是,则对照地址映射表获取对应的进程来处理该数据包;如果不是,则将该数据包存储于缓存中,继续接收下一个数据包,并解析该数据包,判断是否标识同一个请求,重复该过程直至标识同一个请求的多个数据包被接收完毕,则将worker子进程的指针指向下一个,也即唤醒正在睡眠的下一个worker子进程进行处理。

本发明通过上述过程,终端处于非休眠状态时,终端的apk间隔预设时间向服务器发送心跳包以维持udp链路,终端处于休眠状态时,服务器间隔预设时间向终端的apk发送反向心跳包,因此可靠的保证了进入深度休眠的安卓系统的udp长连接。正因为保证了udp的长连接,从而避免了相较于tcp连接的upd的无连接性、无序性(无法标识数据的前续后继),进而通过master进程和fork进程对数据包的有序处理,以及worker子进程的改进处理机制,还可解决在udp数据包无序性情况下丢包时常用的冗余传输机制(一般采用较多的是延时双发,双发指的是将原本单发的前后连续的两个包合并成一个大包发送,这样发送的数据量是原来的两倍),采用本申请的方案,无需采用冗余传输机制,即可确保数据包的传输的稳定性。

尽管结合优选实施方案具体展示和介绍了本发明,但所属领域的技术人员应该明白,在不脱离所附权利要求书所限定的本发明的精神和范围内,在形式上和细节上可以对本发明做出各种变化,均为本发明的保护范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1