博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GS LiveMgr心跳管理类
阅读量:4581 次
发布时间:2019-06-09

本文共 2935 字,大约阅读时间需要 9 分钟。

struct LiveMgr{private:    int                            m_nCount;            ///< 管理数量    std::vector
m_vecChannels; ///< 所有channel std::shared_ptr
m_spTimer; ///< 定时器 public: std::function
m_fnTimeOutDisconnect; void Init(int nMaxGcNumb); bool IsLive(int nChannelId) { return !!(m_vecChannels[nChannelId]); } void OnLive(int nChannelId) { m_vecChannels[nChannelId] = GetTickCount(); } void Add(int nChannelId) { m_nCount++; m_vecChannels[nChannelId] = GetTickCount(); } void Remove(int nChannelId) { m_nCount--; m_vecChannels[nChannelId] = 0; } void Check(); int GetLinks() { return m_nCount; } };这个是心跳管理类GS初始化的时候m_LiveMgr.m_fnTimeOutDisconnect = std::bind(&GameServer::TimeOutDisconnect, this, ph::_1);m_LiveMgr.Init(GetMaxGcNumb());void LiveMgr::Init(int max_gc_numb){ ///创建内部定时检查的定时器,5s执行一次,不过为了现在方便把定时器关闭了 m_spTimer.reset(GetPlug(TimerFactory)->createTimer()); m_spTimer->regTimer(std::bind(&LiveMgr::Check, this)); m_spTimer->setInterval(5 * 1000); //为调试先关掉 //m_timer->start(); m_vecChannels.resize(max_gc_numb);//m_vecChannels保存的所有channel最新的包跟新时间,注意这个默认初始化为0 m_nCount = 0;}那这个是什么时候更新的呢if(rPkt.is_data){ if(!rPkt.data) return false; GameChannel* pGC = m_vecChannel[rPkt.channel_id]; if(pGC) pGC->OnReceiveData(rPkt.data, rPkt.size); m_LiveMgr.OnLive(rPkt.channel_id);//看来这个是每接收一个包的时候将channel的最新时间更新一下}void OnLive(int nChannelId){ m_vecChannels[nChannelId] = GetTickCount();}看看这个5s定时回调的函数做了什么void LiveMgr::Check(){ size_t uNow = GetTickCount(); for (size_t i = 0; i < m_vecChannels.size(); ++i)//遍历所有channel,这个效率??? { size_t uLastTick = m_vecChannels[i]; //uLastTick为0表示没有连接,这句就说明连接了并且15没有接收到数据了,就认为其断线了,会走下线处理的 //想当时测试的时候把网线拔了,此时libevent是不能收到事件的,GS他的连接还是在上面的,如果把定时器打开,15秒后会将其删除的 if(uLastTick && uNow - uLastTick > 15 * 1000) { m_fnTimeOutDisconnect(i); Remove(i);//需要将m_vecChannels对应位置赋值为0,表示没有连接,刚才我还在想这边把socket关闭了,不会受到断开通知,这里处理了就对了 } }}//看看这个function做了什么做相应的下线处理,并关闭网络层的socketvoid GameServer::TimeOutDisconnect(int nChannelId){ try { GameChannel* pGC = m_vecChannel[nChannelId]; pGC->OnDisconnect();//玩家下线处理,回头看玩家下线在详看 if(!pGC->m_pMap) { //PushFreeQueue(pGC); //m_vecChannel[nChannelId] = NULL; AutoFreeGC(pGC); } m_spDataLayer->Close(nChannelId);//这个属于主动断开客户端的连接,libevent那边调用close_channel放入下线队列中,主线程去关闭socket,这个过程应该很清楚了 } catch (...) { DWORD e = GetLastError(); Plug::PlugMessageBox(L"m_spTCPServer->close_channel异常了啊!"); }}//我在想,当时踢玩家下线,是因为那边放入释放队列,60s之后关闭socket,此时客户端收到通知但对于拔网线,那客户端好像也能收到通知,服务端心跳检测关闭时永远都不能收到通知的,那客户端怎么会收到通知的呢,来试验一下

 

转载于:https://www.cnblogs.com/zzyoucan/p/4116633.html

你可能感兴趣的文章
[洛谷P5057][CQOI2006]简单题
查看>>
多线程同步的几种方法
查看>>
数据结构-冒泡排序
查看>>
关于程序状态字寄存器PSW(Program Status Word)与多核多线程
查看>>
mybatis的缓存
查看>>
java 缓冲流 Buffer
查看>>
7月23号=》261页-265页
查看>>
软考知识点梳理--综合布线
查看>>
Mysql5.6主从热备配置
查看>>
VS2010DebugView捕捉
查看>>
mfix中更改time dependent VTK filename的最大时间步数的容量
查看>>
Windows7安装 docker-compose的过程
查看>>
关于nodeJS多线程的支持,目前看来无法实现,讲解v8的一些东西
查看>>
php递归创建文件夹的两种方法
查看>>
6.新增事件
查看>>
|洛谷|二分|P1182 数列分段Section II
查看>>
少儿编程Scratch第四讲:射击游戏的制作,克隆的奥秘
查看>>
Oracle学习第七课-表连接及其应用
查看>>
Python基础篇【第十三篇】:面向对象
查看>>
bzoj 2465 小球
查看>>