对于IM或实时消息推送技术来说,客户端的心跳算法几乎是必备品,尤其当前复杂的移动网络环境下,网络心跳保活算法的优劣更是决定了您的APP即时数据收发的实时性和用户体验,非常地关键。

为什么TCP连接需要心跳?

因为运营商有一个NAT超时:因为IP v4的IP量有限,运营商分配给手机终端的IP是运营商内网的IP,手机要连接Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网IP、端口到内网IP、端口的对应关系,以确保内网的手机可以跟Internet的服务器通讯,大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰NAT表中的对应项,造成链路中断。

所以我们需要间隔一定的时间发送一个数据包来保证当前的TCP连接保持有效,这就是所谓的心跳包。

什么是智能心跳?

智能心跳实际上就是动态的探测到最大的NAT超时时间,然后选定合适的心跳间隔区间去发送心跳包,同时在网络状况发生变化的时候能够动态的调整心跳间隔时间;如果心跳间隔不合适,例如心跳间隔过短,那么可能导致频繁的唤醒手机发送心跳包,增加耗电,心跳间隔过长,可能导致这条TCP连接已经无效但是无法及时的检测到,只能等待下一个心跳包发送的时候才能感知到,所以会导致消息接收延迟,所以探测到一个合适的心跳间隔是非常重要的,把耗电和消息接收及时性综合折中来取得一个最佳的体验。

本文要探讨的二分法智能心跳策略

1心跳变量定义

探测心跳:程序采用不确定的时间间隔去发送心跳,目的是为了得到最大NAT超时时间

稳定心跳:当探测心跳探测到了NAT超时时间那么就会选定比这个时间点稍微小一点的时间来作为稳定心跳,以后就一直以这个稳定时间去发送心跳

minHeart:最小的心跳间隔

maxHeart:最大的心跳间隔

curMinHeart:初始值为minHeart,变换过程中的最小心跳

curMaxHeart:初始值为maxHeart,变换过程中的最大心跳

step:心跳探测步长

maxSuccessCount:稳定心跳成功次数的最大值,用来动态向上探测

maxFailedCount:心跳连续失败次数最大值,用来向下探测

curHeart:当前正在使用的心跳间隔,默认270秒,这个值可以根据不同地区的心跳区间大数据采集统计然后再设置

timeout:心跳超时时间,我们当前设置为20秒,这个其实可以调整的更小,5秒~10秒,之所以设置为20秒是考虑到网络很不好的情况下可能心跳返回的比较慢,所以间隔设的大一些

heartbeatStabledSuccessCount:稳定心跳连续成功的次数

heartbeatFailedCount:心跳连续失败的次数

networkTag:网络环境标识,对于数据网络来说分为电信,联通,移动;对于wifi来说是用wifi的名称来区分的,因为每个运营商的网络环境都可能有不同的NAT超时,所以在网络环境变换的时候要重新调整心跳。

上调curHeart(心跳成功的时候)

把当前的成功心跳区间保存到列表中

curMinHeart = heartbeat.curHeart;

如果当前心跳是稳定心跳,heartbeatStabledFailedCount

= 0;heartbeatStabledSuccessCount++;如果当前心跳不是稳定心跳,curHeart = (curMinHeart

+ curMaxHeart) / 2,然后直接执行第6步

判断heartbeatStabledSuccessCount是否大于maxSuccessCount,如果大于的话就上调maxSuccessCount的上限,可以乘以2,或者递增固定值,这个可以自己决定,我们是maxSuccessCount默认为20,所以maxSuccessCount

= maxSuccessCount + 20;

从成功心跳列表选择比当前稳定心跳更大一级心跳,如果有就把这个作为新的稳定心跳,如果没有:curMaxHeart

= maxHeart;curHeart = (curMinHeart + curMaxHeart) /

2;然后再重新以curHeart开始向上探测心跳

判断curMaxHeart - curMinHeart <

10是否满足,如果满足并且当前心跳还不是稳定心跳:curHeart =

curMinHeart;把二分法比较小的那个值作为稳定心跳,然后探测结束,进入稳定心跳,这里之所以这么做是因为二分法的一个特点,二分法的一个临界值就是curMaxHeart

=

curMinHeart,到最后curMinHeart和curMaxHeart很接近的时候其实(curMaxHeart+curMinHeart)==

2*curMinHeart

==2*curMaxHeart,所以会导致二分法计算出来的curHeart和curMinHeart,curMaxHeart相差就几秒,这是没什么意义的,设置一个10秒的区间来让心跳尽快进入稳定状态

下调心跳(心跳失败的时候)

heartbeatStabledSuccessCount=0;

curMaxHeart = curHeart;

如果是稳定心跳失败了,heartbeatStabledFailedCount++;并且判断heartbeatStabledFailedCount>maxFailedCount,如果是则从成功心跳列表中选择比当前心跳略小一级的心跳并把这个心跳作为新的稳定心跳,要是不存在略小一级的成功心跳,那么curMinHeart

= minHeart;curHeart = (curMinHeart + curMaxHeart) / 2;

如果是探测心跳失败了,curHeart = (curMinHeart + curMaxHeart) / 2;

判断curMaxHeart - curMinHeart < 10,如果满足并且当前心跳不是稳定心跳:curMinHeart = minHeart。

本算法的最终探测效果

以270秒作为curHeart开始探测,minHeart为60秒,maxHeart为300秒,在我们公司的wifi或者数据网络环境下:270,285,292就能够达到稳定心跳,最终稳定心跳会比292小10秒。也就是282秒作为稳定心跳,这里面大概在14分钟之内alarm了三次,如果把maxHeart上调的话探测到稳定心跳的时间会变长,不过平均alarm次数会降低,因为心跳周期在不断变长。即时通讯开发

当达到稳定心跳后,在稳定心跳成功发送20次后会再次尝试上调心跳,如果由于网络环境不稳定导致当前的心跳可能失败次数超过了5次,那么就会下调心跳,总之做到一个原则,严格控制下调条件,能不下调就尽量不下调。

和微信智能心跳算法的对比

【1】更加省电:微信智能心跳是按照从最小还是逐渐递增的去探测的,所以在网络环境不好的条件下前期可能一直探测不上来,心跳周期一直维持在一个较小的范围,导致频繁的alarm,耗电,微信智能心跳探测过程:60秒短心跳,连续发3次后开始探测,90,120,150,180,210,240,270,这个过程中一共耗费24分钟,alarm了10次,在前14分钟之内alarm了8次,而二分法智能心跳前14分钟才唤醒3次。

【2】网络环境差的情况下不会频繁的唤醒:当网络环境很不好的情况下,心跳可能会经常失败,微信智能心跳由于是从下往上上调心跳,可能一直维持在一个间隔周期较小的心跳,会频繁alarm,二分法是从上往下下调心跳,因此心跳周期是逐渐缩小,一开始不会频繁的alarm,比较省电。

【3】探测周期短:微信智能心跳是逐渐的通过累加探测步长来上调心跳,上调的趋势比较稳定,但是如果step设置的比较小,那么会导致上调缓慢,探测到稳定心跳所需要的时间比较长(24分钟);二分法智能心跳的心跳调整波动比较大,成功了就上调一半,失败了就下调一半,所以探测到稳定心跳的时间会比较短(14分钟),但是其实这个都是相对的,如果NAT超时时间为2分钟,那么微信智能心跳一下子就能探测到了,而二分法智能心跳要调整好多次,反正是看NAT超时时间距离最初开始探测的curHeat比较接近,所以curHeart可以通过大数据搜集分析,针对各个地区给出不同的curHeart。

【4】探测期间不够稳定:微信智能心跳的探测过程很稳定,基本不会导致心跳失败,因为它是从最小的开始探测;二分法智能心跳就不一样了,以为curHeart的调整波动比较大,一开始探测一下子上调或者下调一半很容易就超出NAT超时时间,在探测前期会有比较频繁的失败心跳;当然,这个也是相对的,最终都要取决与curHeart的初始值,minHeart,maxHeart,如果这些值设置的合适,那么二分法智能心跳将会很快的探测到稳定心跳。

Android机子上存在的问题

也就是Android系统里alarm的对齐唤醒问题。国内的手机厂商例如华为,魅族,小米都是自定制的android系统,对于AlarmManager都有对齐唤醒策略,因此会导致心跳alarm的时间不准确,例如设置了270秒alarm一次,但是在这些手机上可能要推迟到300秒才能唤醒,那么问题来了,如果NAT超时时间是2分钟,而这些手机的alarm最小间隔是5分钟,那就坑了,永远无法探测到最佳心跳,你设置120秒的alarm,手机系统也给你延迟到5分钟才执行alarm,不过这种情况只有在手机休眠的时候才会对齐唤醒,在手机不休眠的时候,我侧过,alarm计时还是准确的。

分享一种Android端IM即时通讯智能心跳算法相关推荐

  1. android 即时通讯 xmpp,基于xmpp实现android端实现即时通讯

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 简单介绍一下asmack中常用到的方法属性 connection.getAccountManager().createA ...

  2. 聊一聊Web端的即时通讯

    聊一聊Web端的即时通讯 Web端实现即时通讯的方法有哪些? - 短轮询 长轮询 iframe流 Flash Socket 轮询 客户端定时向服务器发送Ajax请求,服务器接到请求后马上返回响应信息并 ...

  3. websocket 发送图片_基于WebSocket的web端IM即时通讯应用的开发

    基于WebSocket的web端IM即时通讯应用的开发 功能列表: 1.Web端的IM即时通讯应用 2.支持上线.下线.实时在线提醒 3.单聊.群聊的建立 4.普通文字.表情.图片的传输(子定义富文本 ...

  4. Android嵌入Udesk即时通讯网页插件(一、入门)

    作者:张振琦 Android 系统上实现Udesk即时通讯,除了使用Udesk提供的原生sdk以外还可以嵌入Udesk提供的即时通讯网页插件.Udesk即时通讯网页插件的内容,大家可以参考<Ud ...

  5. 岁末年初3Q大战惊现高潮,360震撼推出Android 3Q IM即时通讯

    岁末年初3Q大战惊现高潮,360震撼推出Android "3Q" IM即时通讯 看过了QQ和360斗争的开端高潮,当然现在还不能说这场斗争已经结束,在我看来这次的事件未尝不是一个适 ...

  6. 3Q大战现高潮,360 推出Android 3Q IM即时通讯,岁末年初3Q大战惊现高潮

    岁末年初3Q大战惊现高潮,360震撼推出Android "3Q" IM即时通讯 看过了QQ和360斗争的开端高潮,当然现在还不能说这场斗争已经结束,在我看来这次的事件未尝不是一个适 ...

  7. 基于Android开发的即时通讯聊天app

    基于Android开发的即时通讯聊天app 前言 即时通讯(Instant Messaging,简称IM)在互联网中应用十分广泛,它可以和很多的领域结合,发挥十分重要的作用.比如金融行业的支付宝.各大 ...

  8. 环信 “和未来有约”移动IM新时代分享沙龙——做最开源的即时通讯云平台

    9月13日下午,环信与i黑马共同主办了"和未来有约"移动IM新时代分享沙龙. CSDN移动运营总监李涛担任本次活动的主持人,环信即时通讯云CEO刘俊彦.节操精选CEO陈桦.青云商务 ...

  9. Socket.IO介绍:支持WebSocket、用于WEB端的即时通讯的框架

    一.基本介绍 WebSocket是HTML5的一种新通信协议,它实现了浏览器与服务器之间的双向通讯.而Socket.IO是一个完全由JavaScript实现.基于Node.js.支持WebSocket ...

最新文章

  1. 因融资失败,应用崩溃,3 名程序员被“祭天”!
  2. 开启mysql远程访问的权限
  3. java Gregorian,Java GregorianCalendar getTimeZone()用法及代码示例
  4. sip中的100trying到底有啥用
  5. linux安全 4a标准_Linux的未来,提高安全性的开放标准等等
  6. Typora导出PDF时一直处于正在导出的状态
  7. anaconda查看删除增加镜像源
  8. 华为云备份会上传私密相册吗_华为、小米都是国产手机,为啥文件夹却是“英文”?哪些能删除?...
  9. Python如何开发一款连连看脚本,第一必须是我。
  10. 单节2A锂电池充电芯片方案,PD和QC快充充电器5-12V输入
  11. 将matlab代码转换成C代码
  12. android自动亮度流程,Android 如何实现亮度自动调节
  13. 触摸板把计算机从休眠状态唤醒,win10笔记本盒盖唤醒后触摸板失灵的处理方法...
  14. 真正的软件测试实习一
  15. css和html的用法,HTML与CSS之CSS的基本使用
  16. 编程设计一个基于条件风险最小的Bayes分类器
  17. 阿里巴巴2019实习生招聘正式启动!
  18. git点击pull后没有同步_关于git pull时出现的问题及解决反思
  19. 【JAVA程序设计】(C00043)基于SSM非maven的人事管理系统
  20. 面试中人力资源部常问的问题

热门文章

  1. #300. 【CTSC2017】吉夫特
  2. 产品经理数据分析入门指南
  3. Top 25 sourceforge上开源项目介绍
  4. 2015年,我的创业记忆片段
  5. 《娱乐至死》读书笔记(part6)--教育的目的是让学生们摆脱现实的奴役,而现在的年轻人为了适应现实而改变自己
  6. 今日小程序推荐:汇率即时查-打通微信直接搜一搜
  7. 5日均线在c语言中的写法,一文学会正确运用5日均线!(图解)
  8. 【完美解决】爬虫伪装代理IP方案
  9. ubuntu虚拟机中的vscode:扩展失败XHR Failed
  10. ibm服务器修复安装win7系统,联想thinkpad无法开机重装win7,教你重装系统攻略