作者回复: 是的👍
作者回复: 比较常见的有二分法。
作者回复: 其实就是下一次动态调整的心跳间隔是:当前已经确认的安全的心跳间隔最大值 和 已经确认的心跳探测过大的最小值 的中间均值。比如上一次心跳间隔是4分钟,而且连续N次都成功ack了,那么当前已经确认的安全的心跳间隔是4分钟,假设已经确认10分钟时心跳间隔过大了,那么下一次调整的心跳就是 4 + 10 / 2 = 7分钟。
作者回复: 具体是哪个图呀,理解不太对,心跳和推送是独立的,并不会在推送的时候进行检测,一般会由独立的定时器来根据一定时间内socket中是否有数据收发来定时触发的。
作者回复: tcp的keepalive开启比较简单,比如netty下可以通过如下代码开启:
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
另外tcp keepalive的心跳间隔的配置也需要修改一下系统的/etc/sysctl.conf,类似下面:
net.ipv4.tcp_keepalive_time=120
net.ipv4.tcp_keepalive_intvl=30
net.ipv4.tcp_keepalive_probes=3
作者回复: 会双推,走APNs不会直接落地app的db,苹果会根据应用在前台还是在后台来决定要不要展示APNs走通知栏的消息。现在也有很多应用支持应用在前台时也展示通知栏的消息,看具体需求。
作者回复: 在线状态可以在用户完成上线操作后记录到uid维度的存储里供使用。保活机制不一定能保证用户一直在线,只是能降低运营商NAT超时导致连接被强制中断的概率,同时通过心跳保活还能及时发现连接是否可用,从而快速进行重连,来提升连接的可用性。
作者回复: 因为tcp本身是一个虚拟连接,中间链路断开的话另一端是感知不到的,另外,移动运营商的NAT会对一段时间没有数据传输的连接切断,所以对于维护高可用的一条长连接心跳是必不可少的。
作者回复: 心跳间隔是多少?外网的中间路由环节和运营商网络都可能在 一个连接一段时间没有数据传输的时候 从NAT表删除这个连接的映射。所以心跳间隔最好不要大于5分钟。
作者回复: 一般可以采用二分法来进行心跳探测。
作者回复: 一种方式是客户端采用固定timer来定时发送心跳包,也可以在客户端没有消息收发后的一段时间才可以发送心跳包,这样能节约一些流量。
作者回复: 是个好想法,不过QUIC之所以能够实现抽象的connection id应该也是得益于底层依赖的UDP是无状态传输协议,基于TCP之上要解决连接迁移的问题估计会很难。要是你有一些思路咱们可以继续探讨一下。
作者回复: 结合使用是没问题的,tcp keepalive和应用层心跳配合使用,当出现消息收发问题的时候,能够协助我们发现是网络层问题还是应用层问题。
作者回复: 服务端不知道客户端的固定连接地址呀,所以重连一般都是由客户端发起。服务端一般不需要发送心跳,是由客户端来发送心跳,服务端一段时间没有收到客户端的心跳包的时候就可以判断连接异常,主动断开等客户端重连上线就可以了。
作者回复: 是指客户端发送心跳包的间隔。
作者回复: 心跳包的设计貌似没有固定的设计规范,目的就是尽量精简,比如只包括通用Header的空包,或者body内容是当前心跳间隔(智能心跳可能需要用到)。