再看GS接包过程 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);//回调GC中相关函数 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();//m_pDataLayer,GC直接发包到客户端 pNewGC->m_pShare = this; pNewGC->m_pAsynDBC = this->m_spAsynDBC.get();//GC直接跟数据库打交道 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();//做人物下线收尾工作,该通知map,数据库访问操作,等,根据玩家的状态来 //如果未进地图就下线,直接断开;不用保存角色详细数据,可直接放入释放队列中 if (!pDisconnectGC->m_pMap)//如果进入地图需要从map返回数据然后保存数据库 { AutoFreeGC(pDisconnectGC);//如果没有数据库访问直接释放,或者放到队列等无数据库访问在释放 } } m_LiveMgr.Remove(rPkt.channel_id); } } return false; }