GS发包到MS

GS发包到MS(GS,MS包交互过程)
例:人物上线
首先看看其实如何确定是哪张地图的
数据库首先只保存一个mapid
在share初始化的时候已经初始化了所有map,并保存了map的指针信息,其key就是mapid
if(rActorEx.GetMapID() <= 0)
    rActorEx.SetMapID(1009);
int mapID = rActorEx.GetMapID();
rActorEx.m_nBodyID = m_pShare->TGetnBodyId(rActorEx.GetProf(), rActorEx.GetSex());//现在那个bodyid用到了

m_pMap = m_pShare->GetMapByMapId(mapID);//通过mapid就能获得map指针信息
if(!m_pMap)
{
    m_ActorId = 0;
    return;
}

m_pMap->Gs2MsData(gs2ms_add_player, m_nChannelId, (void*)&rActorEx, sizeof(rActorEx));//传入MS,m_pMap即玩家所在地图指针
void Map::Gs2MsData(int cmd, int channel_id, void* data, int len)
{
    MapPkt pkt;
    pkt.channelId = channel_id;
    pkt.data = m_memPool.popPkt(len);//从内存池中分配一块内存出来,以前用的new,然后这个new很容易失败的
    memcpy(pkt.data, data, len);
    pkt.len = len;
    pkt.cmd = cmd;

    PushPkt(pkt);
}
//接下来就是起的线程的作用了
void ThrTransData::PushPkt(MapPkt Pkt)
{
#ifdef BOOST_LOCKFREE
    for (;;)
    {
        if(m_gs2msPkts2.push(Pkt))//将这个包放入无锁队列中
            break;
        cxx11::this_thread::interruptible_wait(1);
    }
#else
    {
        cxx11::lock_guard lock(m_mtxGs2Ms);
        m_queGs2MsPkts.push(Pkt);
    }
#endif
};

void ThrTransData::ThreadLoop()
{
    //SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
    MapPkt Pkt;
    try
    {
        int nCount = 0;
        while (true)
        {
            if(GetDataFromQueue(&Pkt))//从无锁队列中取包
            {
                ProcessPkt(Pkt);
                m_memPool.pushPkt(Pkt.data, Pkt.len);

                nCount++;
                if(nCount > 30)
                {
                    nCount = 0;
                    m_spTimerFactory->driveTimer();
                }
                continue;
            }
            {
                m_spTimerFactory->driveTimer();
                if (m_bStopWork)
                    break;
                cxx11::this_thread::interruptible_wait(1);
            }
        }
    }
    catch(...)
    {
        char szMsg[256] = {0};
        sprintf(szMsg, "【%s】线程%dMap :Pkt.cmd = %d",
            __FUNCTION__, ::GetCurrentThreadId(), Pkt.cmd);
        safe::error_msg(szMsg);
    }
}

void Map::ProcessPkt(MapPkt pkt)
{
    //...
    //gs2ms_add_player属于GS与MS通信的内部协议,内部协议采用树的形式,平行关系就太多了管理不方便
    else if(gs2ms_add_player == pkt.cmd)//玩家进入地图消息,仅仅是个小例子
    {
        PlayerChannel* pPC = new PlayerChannel(this);//这个PlayerChannel是很大的一个模块,玩家信息,回头再看
        //加到地图中,但是并未激活该玩家
        int nChannelId = pPC->OnPlayerEnter(pkt.data, pkt.len);
        m_vecPlayerChannel[nChannelId] = pPC;
        AddPlayer(nChannelId);
    }
    //...
}
时间: 2024-10-25 16:56:29

GS发包到MS的相关文章

客户端发包 GS端接收

客户端发包,GS接收 bool GameServer::ProcessLoop(packet& rPkt)//GS线程做的 { if(false == m_spDataLayer->Recv(rPkt)) return true;//没数据了 if(rPkt.is_data) { if(!rPkt.data)//数据为空 return false; GameChannel* pGC = m_vecChannel[rPkt.channel_id];//m_vecChannelGS里面所有玩家的

移动App服务端架构设计

移动App服务端架构设计 我从事手机app服务端开发现在已经是3个年头,自己也整理出了一套相对好用的服务架构,写出来,跟大家一起分享.如有不足,还请多指教. 一:基础流程图. 其实有一点还需要加上,就是对json的压缩和加密,一来给用户节约流量,二来防止请求被截取破解我们的参数.具体先压缩后加密还是先加密后压缩这个问题看需求. 看到这个架构设计时,你们可能会说如果程序入口挂了,所有的服务都不可以用了. 所以这个架构的弱点在程序入口处,因此要有一(多)台机器做负载,负载的工具可以是HaProxy(

[转]Microsoft Platform SDK 选择及在vc++6.0中的配置

Windows Platform SDK Download Sites: Windows Server 2003 PSDK February 2003 Edition,可以和VC6一起使用.并支持各种目标OS的最后一个版本的SDK. This edition of the SDK supports development for the following platforms: Windows Server 2003 Windows Advanced Server, Limited Editio

项目分析(map复习)

有段时间没看map里面的东西了,刚才看发现功能上增加了一些,在来复习了一次流程初始化每个map建立线程,这个线程有两个功能,1.处理GS发过来的包 2.驱动map里面的定时器GS发过来的包是存在m_gs2msPkts2这个无锁的单消费者,单生产者队列中,只要是GS中不处理的包都要发到MAP中然后每个线程thrTransData::thread()就从m_gs2msPkts2中取包调用Map::process_pkt由于map继承了thrTransData,然后根据绑定调用对于的函数那如果map里

GS与MS之间通信

GS与MS之间通信 注意GS与MS是两个线程,现在是每个map一个线程,他们之间是内部协议进行通信的,那既然是两个线程那如何通信呢,看了net进程通信这个就比较简单了 举个例子 m_pMap->Gs2MsData(gs2ms_add_player, m_nChannelId, (void*)&rActorEx, sizeof(rActorEx));//发送玩家上线包 void Map::Gs2MsData(int cmd, int channel_id, void* data, int le

GS给客户单发包以及m_queGcWait(所有GC共享)

GS给客户单发包以及m_queGcWait(所有GC共享) send_stat BaseChannel::SendCmd(int nCmd, void* pData, int nLen) { Protocol Ptl; Ptl.cmd_type = nCmd; Ptl.content = pData; Ptl.size = nLen; void* tmpBuffer = ms_pSendBuff2C; if (nLen > __GC_MAX_SEND_BUFF_LEN) { ShuiHu::Ge

GS与数据库打交道

GS与数据库打交道 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();//GC直接发包到客户端 pNewGC->m_

share(发包方面)

share(发包方面) 接收所有map发过来的包,这个是GS线程驱动的 { for (;;) { //... if(!itMap.second->RecvData(Pkt)) break; if(Pkt.cmd == ms2gs_转client_cmd) { OnTurnToClient(Pkt.channelId, Pkt.data, Pkt.len); } else if(Pkt.cmd == ms2gs_json) { OnJson(Pkt.channelId, Pkt.data, Pkt

再看GS接包过程

再看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.dat