再看GS线程
void GameServer::ProcessThreadTry()
{
int nCount = ;
packet rcvPkt;
rcvPkt.data = new char[ * ];
//该事件工厂主要创建了两个定时器1.livemgr的检测(即是否是有效的连接)2.道具帮会差异更新数据的获取即定时从道具帮会容器中获取差异需要保存到数据库的这个数据
//3.释放队列的处理,现在玩家下线不是直接把channel删除掉而是放到释放队列中等没有数据库访问时在删除,防止数据库回调出现野指针
I_TimerFactory* pTimeFactory = GetPlug(TimerFactory); for (;;)
{
ProcMapSendData();//处理GameMap里面的包(应该是处理所有Map发过来的包,过程需要再看) m_spAsynDBC->Drive();//数据库回调驱动 bool bRcvRet = ProcessLoop(rcvPkt);//处理网络层发过来的包 ProcMapSendData();//在此处理map发过来的包(不知为什么在执行一次) if(bRcvRet)//看来其实优先处理map,网络,数据库方面的数据的
{
m_spSaveOptMgr->Driver();//道具帮会存储数据库驱动 pTimeFactory->driveTimer();//上面三件事的定时驱动 /**
* [说明]:多进程模式,可能存在未分配成功共享内存而导致发送失败的时候,
* 需要GS这边帮未完成发送的GC发送数据,不然可能存在数据丢失的现象,
* 注意死循环
*/
////既然空闲了,就看看有没有没发出去的数据
if(m_queGcWait.empty())//先判断感觉这样好点,如果和下面的放到一起耦合度高了
{
if (m_bStopWork)
break;
boost::this_thread::interruptible_wait(); //stl的误差太大,用这个精度高//test2
continue;
}
int nMaxCount = ; //最多执行5个GC发送
do //注意别存在死循环
{
int nChannelId = m_queGcWait.front();
m_queGcWait.pop();
GameChannel* pGC = m_vecChannel[nChannelId];
//如果改GC在线且活着,则发送未发送成功的数据,否则清空指令。
if(m_LiveMgr.IsLive(nChannelId) && pGC)//没有被踢下线并且在线
pGC->SendCmdTry();
else
pGC->ClearCmd();//不在线了(遍历剩余队列并归还内存池)
}while(m_queGcWait.size() && --nMaxCount);//m_queGcWait未发送成功的GC队列
}
nCount++;
if(nCount > )
{
pTimeFactory->driveTimer();//当大于50时候强制驱动定时器,不然上面几个比较忙的时候,这个定时器一直得不到驱动,相关函数一直无法执行
nCount = ; }
}
StopWork();
delete[] rcvPkt.data;
} bool GameServer::ProcessLoop(packet& rPkt)
{
if(false == m_spDataLayer->Recv(rPkt))
return true;//没数据了 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);
}
else
{
//网络事件
link_stat stat = (link_stat)rPkt.size;
if (stat == link_stat::link_connected)
{
GameChannel* pNewGC = new GameChannel();
pNewGC->m_nChannelId = rPkt.channel_id;
pNewGC->m_pDataLayer = m_spDataLayer.get();
pNewGC->m_pShare = this;
pNewGC->m_pAsynDBC = this->m_spAsynDBC.get();
pNewGC->m_pLog = this->m_spLog.get(); m_vecChannel[rPkt.channel_id] = pNewGC;
m_LiveMgr.Add(rPkt.channel_id);
}
else if (stat == link_stat::link_disconnected || stat == link_stat::link_connect_failed )
{
GameChannel* pDisconnectGC = m_vecChannel[rPkt.channel_id];
if (pDisconnectGC)
{
//如果进入了地图,保存人物信息时会调用push_freeQueue + 滞空m_Channels[channel_id],
pDisconnectGC->OnDisconnect(); //如果未进地图就下线,直接断开;不用保存角色详细数据,可直接放入释放队列中
if (!pDisconnectGC->m_pMap)
{
AutoFreeGC(pDisconnectGC);
}
}
m_LiveMgr.Remove(rPkt.channel_id);
}
}
return false;
}

最新文章

  1. linux 安装 nginx 及反向代理配置
  2. AlertDialog的六种创建方式
  3. 成员资格、授权 – ASP.NET MVC 4 系列
  4. HTML5商城开发四 多图或多商品的水平滚动展示
  5. 电脑不能浏览网页but能登录qq,解决方案总结
  6. 【Asp.Net】document.getElementById 的属性介绍
  7. lightOJ1370 欧拉函数性质
  8. hdu 4856 Tunnels(bfs+状态压缩)
  9. Redis 中文入库成功,读取数据写入文件乱码问题
  10. IPC之消息队列详解与使用
  11. Legendary Items-微软实习生笔试第一题
  12. 原型及原型链,以及prototype和__proto__属性(笔记便于以后复习)
  13. 关于Jaccard相似度在竞品分析中的一点思考
  14. PowerShell安全修改Windows 10 登陆背景图
  15. mqtt服务器apollo的搭建和测试工具paho的使用
  16. Jquery判断$("#id")获取的对象是否存在
  17. 2018-10-04 [日常]用Python读取word文档中的表格并比较
  18. 4.App非功能测试总结
  19. IdentityServer4 中文文档 -1- (简介)背景
  20. Oracle 12c 容器讲解

热门文章

  1. 关于getSystemResource, getResource 的总结
  2. hdu 2582(数论相关定理+素数筛选+整数分解)
  3. 机器学习(4):数据分析的工具-pandas的使用
  4. Topcoder SRM 663 DIV 1
  5. Putty完全使用方法
  6. UNIX网络编程卷1 server程序设计范式8 预先创建线程,由主线程调用accept
  7. CentOS6.5环境配置笔记
  8. OCP-1Z0-051-题目解析-第16题
  9. base64加密PHP脚本的解码方法
  10. 03_Nginx加入新模块