服務端部分:
1:服務端loginapp.cpp中“void Loginapp::login(Network::Channel* pChannel, MemoryStream& s)”被觸發, 這個函數進行了一系列的檢查,
確定合法後向dbmgr發送一個登陸請求包“(*pBundle).newMessage(DbmgrInterface::onAccountLogin);”, dbmgr也會進行一系列的檢查並將登陸結果返回到loginapp。
- void Loginapp::login(Network::Channel* pChannel, MemoryStream& s)
- {
- ...
- ...
- if(loginName.size() > ACCOUNT_NAME_MAX_LENGTH)
- {
- INFO_MSG(fmt::format("Loginapp::login: loginName is too long, size={}, limit={}.\n",
- loginName.size(), ACCOUNT_NAME_MAX_LENGTH));
- _loginFailed(pChannel, loginName, SERVER_ERR_NAME, datas, true);
- s.done();
- return;
- }
- if(password.size() > ACCOUNT_PASSWD_MAX_LENGTH)
- {
- INFO_MSG(fmt::format("Loginapp::login: password is too long, size={}, limit={}.\n",
- password.size(), ACCOUNT_PASSWD_MAX_LENGTH));
- ...
- ...
- ...
- // 向dbmgr查詢用戶合法性
- Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
- (*pBundle).newMessage(DbmgrInterface::onAccountLogin);
- (*pBundle) << loginName << password;
- (*pBundle).appendBlob(datas);
- dbmgrinfos->pChannel->send(pBundle);
- }
複製代碼
1.1: loginapp得到dbmgr的登錄合法結果後向baseappmgr發送了分配網關(baseapp)請求(registerPendingAccountToBaseapp), 通常是負載較低的一個baseapp進程.
- void Loginapp::onLoginAccountQueryResultFromDbmgr(Network::Channel* pChannel, MemoryStream& s)
- {
- ...
- ...
- ...
- // 如果大於0則說明當前賬號仍然存活於某個baseapp上
- if(componentID > 0)
- {
- Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
- (*pBundle).newMessage(BaseappmgrInterface::registerPendingAccountToBaseappAddr);
- (*pBundle) << componentID << loginName << accountName << password << entityID << dbid << flags << deadline << infos->ctype;
- baseappmgrinfos->pChannel->send(pBundle);
- return;
- }
- else
- {
- // 註冊到baseapp並且獲取baseapp的地址
- Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
- (*pBundle).newMessage(BaseappmgrInterface::registerPendingAccountToBaseapp);
- (*pBundle) << loginName;
- (*pBundle) << accountName;
- (*pBundle) << password;
- (*pBundle) << dbid;
- (*pBundle) << flags;
- (*pBundle) << deadline;
- (*pBundle) << infos->ctype;
- baseappmgrinfos->pChannel->send(pBundle);
- }
- }
複製代碼
1.2:baseappmgr最終返回所分配的baseapp的ip地址等信息,loginapp將其轉發給客戶端(登錄成功協議onLoginSuccessfully,包含baseapp的ip和端口信息)
- void Loginapp::onLoginAccountQueryBaseappAddrFromBaseappmgr(Network::Channel* pChannel, std::string& loginName,
- std::string& accountName, std::string& addr, uint16 port)
- {
- ...
- ...
- ...
- Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
- (*pBundle).newMessage(ClientInterface::onLoginSuccessfully);
- uint16 fport = ntohs(port);
- (*pBundle) << accountName;
- (*pBundle) << addr;
- (*pBundle) << fport;
- (*pBundle).appendBlob(infos->datas);
- pClientChannel->send(pBundle);
- SAFE_RELEASE(infos);
- }
複製代碼
2: 客戶端插件得到返回結果後調用KBEngineApp.cs->login_baseapp()函數開始正式登錄到baseapp。
3:baseapp收到登錄請求
- void Baseapp::loginGateway(Network::Channel* pChannel,
- std::string& accountName,
- std::string& password)
複製代碼
進行了一系列的檢查,包括:賬號是否已經在線,是否可以在這裏登錄等等。
當檢查合法後,向dbmgr發送了一個查詢賬號信息的請求“DbmgrInterface::queryAccount”,dbmgr將查詢到的賬號數據(包括屬性等)返回到baseapp, Baseapp::onQueryAccountCBFromDbmgr
當函數結果爲合法時,根據配置中定義的賬號實體腳本名稱“g_serverConfig.getDBMgr().dbAccountEntityScriptType”創建了Account實體, 同時還創建了一個clientMailbox,賬號實體中調用clientMailbox->方法()即可與客戶端通訊了。
Account實體被創建後, 首先__init__被調用, 接着onEntitiesEnabled被調用, 此時實體正式可用了。
賬號登陸成功後, 客戶端Account.cs中會調用__init__() -> baseCall("reqAvatarList");來請求獲得角色列表,
UI.cs中onReqAvatarList得到結果