概述
一、长连接的定义与心跳说明
我们在客户端(手机APP、浏览器、电脑客户端等)去向服务器请求数据交互的时候,一般是通过网络进行消息的传输。其中依据网络传输协议,与服务器建立的连接都是基于TCP/UDP进行。依据这些,我们可以粗略的认为客户端与服务器建立了能长期进行数据传输的网络通道,这就是长连接。
一般来说,TCP的机制可以为我们提供相对稳定的连接监听,即当客户端主动断开网络连接的时候,服务器也能及时(5秒以内)收到相关动态。但存在一种情况,当客户端被动断开网络连接的时候,例如网线被拔、路由器瞬间短路烧毁等,TCP的保活定时器往往需要很长时间(一般在30分钟以上)才能让服务器知道这条连接已经中断,往往需要使用长连接的场景都伴随着大量的高频度的数据交互,这样就会对我们的业务逻辑造成影响。
为了解决上述问题,于是就有了名为“心跳“的解决方案。即让客户端每隔一定的时间间隔(一般是3秒-10秒不等)向服务器发送一次专门用于标记连接存活的消息,如果几次时间间隔后服务器仍未接收到该消息,就默认该连接已中断,从而执行用户的下线处理。
二、心跳问题解决
笔者这里的模拟场景是游戏连接中的心跳问题解决流程。
基本环境:游戏服务器 + Redis存储玩家数据
1. 初始思路是服务器维护一个玩家在线连接池,同时在玩家身上设置一个时间戳参数,专门用于接收到的玩家心跳消息后进行刷新,服务器会有一个单独线程每隔一段时间检测在线玩家的时间戳,如果超过一定时间就默认断连,执行玩家下线处理。
问题:玩家在偶然情况下会在刚登陆服务器,即还未来得及发送心跳消息刷新时间戳(时间戳还是上次掉线时的时间戳),就被检测线程误伤断连,导致玩家登陆游戏失败。具体表现就是玩家偶尔会无法登陆服务器。
2. 优化思路:在玩家连接到服务器的时候就默认执行了一次心跳消息的发送,执行心跳消息时间戳的刷新。
问题:依旧存在玩家在执行心跳消息处理期间被检测线程误伤断连的可能性。
3. 继续优化:改造检测线程,在玩家身上增加一个时间戳参数用于记录玩家登陆时的时间戳。玩家未登录则对登陆的时间戳检测,检测时间间隔较长;玩家登陆后对心跳时间戳进行检测,检测时间间隔较短。
问题:玩家数据放置在redis中,出现了因为网络抖动造成的redis玩家数据获取失败,导致断连情况出现。
4. 接着优化:将两个记录时间戳的参数从玩家身上取出,单独放置在游戏服务器本地进行维护。具体方法是在每个网络连接上都绑定两个相关的局部时间戳参数,一个在玩家登陆时进行时间戳更新,一个在玩家登陆后进行心跳时间戳更新。这样就保证了时间戳参数获取的可靠性与及时性。
目前的优化只到如此程度,特地写一篇文章分享一下自己的相关优化思路。如果还有可能存在的问题还请大家留言指出。
最后
以上就是火星上过客为你收集整理的长连接心跳问题解决总结的全部内容,希望文章能够帮你解决长连接心跳问题解决总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复