kbengine 登录login过程
服务端部分:
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得到结果