数据库发包

现在就来看看数据库发包模式

这个用到了抽象工厂模式

其实经理的那个差不多都是注册具体工厂到抽象工厂,只是这里不是抽象工厂而是PktFactoryMgr功能和抽象工厂差不多

{
#define __REGISTER_DB_PKT_CREATEFUNCTION(DBOptClassType)    
    Register<DBOptClassType>(PktSingleFactory<DBOptClassType>::GetOrCreateInstance());

    __REGISTER_DB_PKT_CREATEFUNCTION(AskActorList);//注册包工厂到m_vecPktConstructor中
    __REGISTER_DB_PKT_CREATEFUNCTION(AskActorInfo);
    __REGISTER_DB_PKT_CREATEFUNCTION(AskActorInfoEx);
    __REGISTER_DB_PKT_CREATEFUNCTION(AskUserInfo);
}
m_vecPktConstructor[pFactory->GetPktID()] = 
            new FnPktCreate(std::bind(&PktSingleFactory<T>::CreatePkt, pFactory));
我任务PktSingleFactory就相当于具体工厂,将具体工厂类注册金抽象工厂类

void asynDBCenter::GetUserInfo(std::function<void(bool bExist, const ShuiHu::UserInfo& hr)>* fnGetUserInfo, const char* pszName)
{

    //抽象工厂根据注册进去的具体工厂创建具体产品,但有点疑问就是抽象工厂具体工厂可以创建多个具体产品类的实例,但CreatePkt是显示的去new
    DB::AskUserInfo* pAskPkt = dynamic_cast<DB::AskUserInfo*>(m_pPktFacMgr->CreatePkt(DB::eDBOpt_AskUserInfo));

    //InterruptStream流内部封装操作,没什么
    DB::InterruptStream SendStream(m_pSendBuffer, eMaxSendBufferSize);
    DB::DBOptID eOptID = pAskPkt->GetID();
    SendStream.CopyIn(&eOptID, sizeof(DB::DBOptID)); // 操作ID

    pAskPkt->m_uFlag = (unsigned __int64)fnGetUserInfo; // 识别标记
    strncpy(pAskPkt->m_aUserName, pszName, MAX_NAME_LEN);
    pAskPkt->Write(SendStream);
    
    //DestroyPkt又显示的delete,每次发包去new,delete容易造成内存碎片
    m_pPktFacMgr->DestroyPkt(pAskPkt);

    PushShmInter(SendStream);
}

DBSvr那边根据接收的数据创建介入式流,从其中读取ID创建相应的包,然后从包从介入式流中读取数据,在根据包的ID解析数据访问数据库
原文地址:https://www.cnblogs.com/zzyoucan/p/4354746.html