美文网首页
移动端心跳包

移动端心跳包

作者: topone37 | 来源:发表于2019-12-24 17:54 被阅读0次

移动端心跳包

TCP的心跳机制

TCP协议,本身拥有一个KeepAlive机制,既然有了心跳机制,为什么还要在应用层面设计一个心跳包呢?

  1. TCPKeepAlive机制的局限, 应用层面的可用不等同于网络层面连接的存活状态

    TCP层面的keepalive存在更多意义上是为了检测两端连接是否正常,注重点是在于连接的本身,默认TCP的超时时间2小时太长,还会存在一些让keep-alive失效的场景

    • keepAlive只能检测连接存活,而不能检测连接可用,比如服务器因为负载过高导致无法响应请求但是连接仍然存在,此时keepalive无法判断连接是否可用

    • 如果TCP连接的另一端突然掉线,这个时候我们并不知道网络已经关闭。而此时,如果有发送数据失败,TCP会自动进行重传。重传包的优先级高于keepalive的包,那就意味着,我们的keepalive总是不能发送出去。 而此时,我们也并不知道该连接已经出错而中断。在较长时间的重传失败之后,我们才会知道。

  2. HTTPKeepAlive机制:复用tcp连接

    • HTTP/1.0之前,默认使用短连接,每进行一次HTTP操作,就简历一次连接,但任务结束就中断连接,

    • HTTP/1.1起,默认使用长连接,用以保持连接特性,复用同一个TCP连接,串行的来完成传递请求-响应数据,长连接的优势是节省了创建连接的耗时。

应用层面的HeartBeat设计

客户端开启一个定时任务,定时向已经建立连接的服务端发送请求(心跳包),服务端接收到后,就需要处理该特殊请求,返回响应,如果没有收到心跳响应多次,就认为连接不可用,进行重连

  • 心跳包的设计

    • 定时任务,频率设计(固定,)

    • 连接闲置才保活,避免流量浪费

    • 重试策略

    • 特定场景的触发,点亮屏幕,切换前台保证信息及时收到

    • 心跳间隔要小于NAT超时时间

MQTT Android心跳包 AlarmPingSender

  • 定义了一个心跳包发送接口
  public void init();
  //开发发送心跳包
  public void start();
  //停止发送心跳包,可能是出错,获取连接关闭
  public void stop();
  //下一次心跳包的发送
  public void schedule(long delayInMilliseconds);
  • Android端 心跳包实现类
private MqttService service = mqttService;
    ​
    public void start() {
     String action = "mqtt_heart_beat"
     //注册上对应广播接收器
     service.registerReceiver(alarmReceiver, new IntentFilter(action));
     //准备好 PendingIntent,每次都是定时发送一个广播
     pendingIntent = PendingIntent.getBroadcast(service, 0, 
     new Intent(action), PendingIntent.FLAG_UPDATE_CURRENT);
     //设置好下一次心跳包的发送
     schedule(interval_time);
    }
    //准备好下一次心跳
    public void schedule(long delayInMilliseconds) {
     //下一次心跳时间
     long nextAlarmInMilliseconds = System.currentTimeMillis()
     + delayInMilliseconds;
     //获取alarmManager
     AlarmManager alarmManager = (AlarmManager) service
     .getSystemService(Service.ALARM_SERVICE);

     //AlaramManager的兼容处理 定时任务
     if(Build.VERSION.SDK_INT >= 23){
     alarmManager.setExactAndAllowWhileIdle(
     AlarmManager.RTC_WAKEUP,nextAlarmInMilliseconds,pendingIntent);
     } else if (Build.VERSION.SDK_INT >= 19) {
     alarmManager.setExact(
     AlarmManager.RTC_WAKEUP,nextAlarmInMilliseconds,pendingIntent);
     } else {
     alarmManager.set(                            AlarmManager.RTC_WAKEUP,nextAlarmInMilliseconds,pendingIntent);
     }
     }
    ​

    //停止定时任务
    public void stop() {
     AlarmManager alarmManager = (AlarmManager)service.getSystemService(Service.ALARM_SERVICE);
     alarmManager.cancel(pendingIntent);
    }
    ​
    class AlarmReceiver extends BroadcastReceiver {
     private WakeLock wakelock;

     public void onReceive(Context context, Intent intent) {
     //AlaramManager持有的cpu wake_lock只能保证onReciver方法执行完成,但是我们需要在此处发送心跳包等,所以需要创建一个新的wake_lock
     PowerManager pm = (PowerManager) service
     .getSystemService(Service.POWER_SERVICE);
     wakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, wakeLockTag);
     wakelock.acquire();
    ​
     //心跳包处理相关
     IMqttToken token = comms.checkForActivity();
     wakelock.release();

     }
     }
    // ClientComms#checkForActivity -> ClientStat#checkForActivity
    public MqttToken checkForActivity() {
     //将pingComond加入到发送数据流中
     pendingFlows.insertElementAt(pingCommand, 0);
     //获取下次心跳包时间
     nextPingTime = getKeepAlive();
     //准备下一次心跳包的发送
     pingSender.schedule(nextPingTime);
    }

附录:

  • NAT超时

    • 因为 IP v4IP量有限,运营商分配给手机终端的 IP是运营商内网的IP,手机要连接Internet,就需要通过运营商的网关做一个网络地址转换(Network Address TranslationNAT)。简单的说运营商的网关需要维护一个外网IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟Internet的服务器通讯。
    • 大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰 NAT表中的对应项,造成链路中断。
    • 长连接心跳间隔必须要小于NAT超时时间(aging-time),如果超过aging-time不做心跳,TCP长连接链路就会中断,Server就无法发送Push给手机,只能等到客户端下次心跳失败后,重建连接才能取到消息。

思考

  • 心跳机制保证了连接的可用性,保证推送信息的及时收取,但是为了及时收到信息,保活进程也是一个逃不开的手段,后续分析一下,进程的保活的手段

参考链接

相关文章

  • 移动端心跳包

    移动端心跳包 TCP的心跳机制 TCP协议,本身拥有一个KeepAlive机制,既然有了心跳机制,为什么还要在应用...

  • Netty 4.0 实现心跳检测和断线重连

    一、实现心跳检测 原理:当服务端每隔一段时间就会向客户端发送心跳包,客户端收到心跳包后同样也会回一个心跳包给服务端...

  • Netty4 断线重连

    一 、实现心跳检测 原理:当服务端每隔一段时间就会向客户端发送心跳包,客户端收到心跳包后同样也会回一个心跳包给服务...

  • Netty4断线重连

    一 、实现心跳检测 原理:当服务端每隔一段时间就会向客户端发送心跳包,客户端收到心跳包后同样也会回一个心跳包给服务...

  • netty双向心跳的设计

    心跳包:不带消息体 客户端定时20秒发送心跳包 -> 服务端回应 客户端检查60秒内未读到消息,则认为断线,关闭连...

  • 如何保持 SSH 服务不掉线

    常见的保持 SSH 服务不掉线的方法有两种: 服务端发送心跳包 客户端发送心跳包 本篇文章将以 Ubuntu 18...

  • 移动端rem适配

    rem适配 一、移动端适配包 1.安装移动端适配包 2.在 main.js 引入适配包 3.在 index.htm...

  • 抓包工具——fiddler的使用(2)

    fiddler除了可以抓网页端的包,还可以通过设置代理抓手机端的包。 【手机端抓包配置介绍】 在配置移动端证书之前...

  • 2019-09-16 wireshark监控 ( 简 )

    本次小实践是PC端开热点,移动端连入热点进行操作。PC使用wireshark对移动端抓包监控。 wireshark...

  • 在Android上面如何使用带有心跳检测的Socket

    由于移动设备的网络的复杂性,经常会出现网络断开,如果没有心跳包的检测,客户端只会在需要发送数据的时候才知道自己已经...

网友评论

      本文标题:移动端心跳包

      本文链接:https://www.haomeiwen.com/subject/sipfoctx.html