zoukankan      html  css  js  c++  java
  • GS线程

    void GameServer::ProcessThread()
    {
        try
        {//在ui线程里面搞个大try不是说try效率不好吗,难道只是为了出现错误发现在GS线程里面出现的吗
            ProcessThreadTry();
        }
        catch (...)
        {
            DWORD dwErrno = GetLastError();
            
            MessageBox(NULL, L"GameServer::process_thread异常", L"异常", MB_OK);
        }
    }
    
    void GameServer::ProcessThreadTry()
    {
        int nCount = 0;
        packet Pkt;
        Pkt.data = new char[1024 * 100];
        I_TimerFactory* pTimeFactory = GetPlug(TimerFactory);//定时保存还是在这个GS线程里面处理的
    
        for (;;)
        {
            ProcMapSendData();//这个相当重要了,处理map发送给GS的数据
    
            m_spAsynDBC->Drive();//驱动数据库回调
            m_DBSaveTiming.DriveDBSaveTiming();//驱动定时保存道具,帮会
            bool bRcvDataRet = ProcessLoop(Pkt);//收取网络数据并处理
            ProcMapSendData();//又在这里处理网络数据,不知这个什么意思,故意这么安排的?
    
            if(bRcvDataRet)//缓存里面没有新命令,可以wait一下了
            {
                pTimeFactory->driveTimer();
                //等1ms
                //std::this_thread::sleep_for(std::chrono::milliseconds(1));
                ///对于这个曾经机器人总是在上线的时候人老是少,这个问题我找了好久不知什么原因,因为当时对于网络模块不熟,
                ///但下面这个GC里面没有发送的数据,到GS里面发送,没咋搞懂,GC和GS是在一个线程里面的,应该可以这样做,随后好好看看
                /**
                 * [说明]:多进程模式,可能存在未分配成功共享内存而导致发送失败的时候,
                 *        需要GS这边帮未完成发送的GC发送数据,不然可能存在数据丢失的现象,
                 *        注意死循环
                 */
                ////既然空闲了,就看看有没有没发出去的数据
                if(m_queGcWait.empty())
                {
                    boost::this_thread::interruptible_wait(1); //stl的误差太大,用这个精度高//test2
                    continue;
                }
                int nMaxCount = 5; //最多执行5个GC发送
                do //注意别存在死循环
                {
                    int nChannelId = m_queGcWait.front();
                    m_queGcWait.pop();
                    GameChannel* pGC = m_vecChannel[nChannelId];
                    if(m_LiveMgr.IsLive(nChannelId) && pGC) //如果改GC在线且活着,则发送未发送成功的数据。
                        pGC->SendCmdTry();
                }while(m_queGcWait.size() && --nMaxCount);
            }
            nCount++;
            if(nCount > 50)
            {
                pTimeFactory->driveTimer();
                nCount = 0;
    
            }
        }
    }
    
    bool GameServer::ProcessLoop(packet& rPkt)
    {
        if(false == m_spDataLayer->Recv(rPkt))
            return true;//没数据了
        
        if(rPkt.is_data)///网络是不是数据,有的是libevent事件
        {
            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();
                m_vecChannel[rPkt.channel_id] = pNewGC;//有玩家连接
                pNewGC->m_nChannelId = rPkt.channel_id;
                pNewGC->m_pDataLayer = m_spDataLayer.get();
                pNewGC->m_pShare = this;
                pNewGC->m_pAsynDBC = this->m_spAsynDBC.get();
                //gc->m_db = this->m_asyndb->getSynDBptr();//把地址复制一份给GameChannel::m_db,让其具有数据库操作权
                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)
                    {
                        //PushFreeQueue(pDisconnectGC);
                        //m_vecChannel[rPkt.channel_id] = NULL;
                        AutoFreeGC(pDisconnectGC);
                    }
                }
                m_LiveMgr.Remove(rPkt.channel_id);
            }
        }
        return false;
    }
    这个就是简单的介绍,GS这个模块很重要
    GS
    数据库 GameMap 网络 跨地图操作(道具,帮会,关系),这些都和GS有联系
  • 相关阅读:
    python struct使用
    pythonunittest(1)
    python os.path模块学习(转)
    pythonunittest(2)
    主机+虚拟机Ubuntu+开发板互相ping通
    wince 外部中断调用可安装ISR错误(data abort)
    wince firstboot.nb0 的大小的问题解决
    wince 串口索引超过10个解决方法
    wince uboot 启动 wince
    zigbee 天线的设计
  • 原文地址:https://www.cnblogs.com/zzyoucan/p/4111907.html
Copyright © 2011-2022 走看看