一直都想找个时间研究下kbengine,毕竟kbe是一款功能强大,实力非凡的开源游戏服务器引擎,可以说在游戏服务器这块,目前还没看到能拿得出来的有kbe这么完善的功能齐全的性能如此优异的服务器框架了吧。
好了废话不多说,现在开始撸,
我的想法是这样的,在文章中我只会说重点的部分,还有我觉得不太好理解的地方,细节我会附件一个思维导图帮助大家细致的了解。
首先难理解的是kbe使用了大量的宏,不仔细看你会一头雾水,
下面是第一段代码,当然是main.cpp里面的了这个地方不理解,其他的看着都蛋疼
#include "server/kbemain.h"
#include "loginapp.h"
#undef DEFINE_IN_INTERFACE
#include "client_lib/client_interface.h"
#define DEFINE_IN_INTERFACE
#include "client_lib/client_interface.h"
#undef DEFINE_IN_INTERFACE
#include "machine/machine_interface.h"
#define DEFINE_IN_INTERFACE
#include "machine/machine_interface.h"
#undef DEFINE_IN_INTERFACE
#include "baseappmgr/baseappmgr_interface.h"
#define DEFINE_IN_INTERFACE
#include "baseappmgr/baseappmgr_interface.h"
#undef DEFINE_IN_INTERFACE
#include "cellappmgr/cellappmgr_interface.h"
#define DEFINE_IN_INTERFACE
#include "cellappmgr/cellappmgr_interface.h"
#undef DEFINE_IN_INTERFACE
#include "cellapp/cellapp_interface.h"
#define DEFINE_IN_INTERFACE
#include "cellapp/cellapp_interface.h"
#undef DEFINE_IN_INTERFACE
#include "baseapp/baseapp_interface.h"
#define DEFINE_IN_INTERFACE
#include "baseapp/baseapp_interface.h"
#undef DEFINE_IN_INTERFACE
#include "dbmgr/dbmgr_interface.h"
#define DEFINE_IN_INTERFACE
#include "dbmgr/dbmgr_interface.h"
#undef DEFINE_IN_INTERFACE
#include "tools/bots/bots_interface.h"
#define DEFINE_IN_INTERFACE
#include "tools/bots/bots_interface.h"
#undef DEFINE_IN_INTERFACE
#include "tools/logger/logger_interface.h"
#define DEFINE_IN_INTERFACE
#include "tools/logger/logger_interface.h"
#undef DEFINE_IN_INTERFACE
#include "tools/interfaces/interfaces_interface.h"
#define DEFINE_IN_INTERFACE
#include "tools/interfaces/interfaces_interface.h"
using namespace KBEngine;
int KBENGINE_MAIN(int argc, char* argv[])
{
ENGINE_COMPONENT_INFO& info = g_kbeSrvConfig.getLoginApp();
return kbeMainT<Loginapp>(argc, argv, LOGINAPP_TYPE, info.externalPorts_min,
info.externalPorts_max, info.externalInterface, 0, info.internalInterface);
}
这个地方主要有两个难理解的地方,
第一个是包含了各种interface头文件,别看只是添加了一个头文件而已其实做了很多事,那"tools/interfaces/interfaces_interface.h"这个来举例,上代码:
/*
This source file is part of KBEngine
For the latest info, see http://www.kbengine.org/
Copyright (c) 2008-2018 KBEngine.
KBEngine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KBEngine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with KBEngine. If not, see <http://www.gnu.org/licenses/>.
*/
#if defined(DEFINE_IN_INTERFACE)
#undef KBE_INTERFACES_TOOL_INTERFACE_H
#endif
#ifndef KBE_INTERFACES_TOOL_INTERFACE_H
#define KBE_INTERFACES_TOOL_INTERFACE_H
// common include
#if defined(INTERFACES)
#include "interfaces.h"
#endif
#include "interfaces_interface_macros.h"
#include "network/interface_defs.h"
//#define NDEBUG
// windows include
#if KBE_PLATFORM == PLATFORM_WIN32
#else
// linux include
#endif
namespace KBEngine{
/**
Interfaces消息宏, 参数为流, 需要自己解开
*/
/**
Interfaces所有消息接口在此定义
*/
NETWORK_INTERFACE_DECLARE_BEGIN(InterfacesInterface)
// 某app注册自己的接口地址到本app
INTERFACES_MESSAGE_DECLARE_ARGS11(onRegisterNewApp, NETWORK_VARIABLE_MESSAGE,
int32, uid,
std::string, username,
COMPONENT_TYPE, componentType,
COMPONENT_ID, componentID,
COMPONENT_ORDER, globalorderID,
COMPONENT_ORDER, grouporderID,
uint32, intaddr,
uint16, intport,
uint32, extaddr,
uint16, extport,
std::string, extaddrEx)
// 请求创建账号。
INTERFACES_MESSAGE_DECLARE_STREAM(reqCreateAccount, NETWORK_VARIABLE_MESSAGE)
// 登陆账号。
INTERFACES_MESSAGE_DECLARE_STREAM(onAccountLogin, NETWORK_VARIABLE_MESSAGE)
// 充值请求
INTERFACES_MESSAGE_DECLARE_STREAM(charge, NETWORK_VARIABLE_MESSAGE)
// 某app主动请求look。
INTERFACES_MESSAGE_DECLARE_ARGS0(lookApp, NETWORK_FIXED_MESSAGE)
// 某个app向本app告知处于活动状态。
INTERFACES_MESSAGE_DECLARE_ARGS2(onAppActiveTick, NETWORK_FIXED_MESSAGE,
COMPONENT_TYPE, componentType,
COMPONENT_ID, componentID)
// 请求关闭服务器
INTERFACES_MESSAGE_DECLARE_STREAM(reqCloseServer, NETWORK_VARIABLE_MESSAGE)
// 请求查询watcher数据
INTERFACES_MESSAGE_DECLARE_STREAM(queryWatcher, NETWORK_VARIABLE_MESSAGE)
// 请求擦除客户端请求任务。
INTERFACES_MESSAGE_DECLARE_ARGS1(eraseClientReq, NETWORK_VARIABLE_MESSAGE,
std::string, logkey)
// 开始profile
INTERFACES_MESSAGE_DECLARE_STREAM(startProfile, NETWORK_VARIABLE_MESSAGE)
// 请求强制杀死当前app
INTERFACES_MESSAGE_DECLARE_STREAM(reqKillServer, NETWORK_VARIABLE_MESSAGE)
// executeRawDatabaseCommand从dbmgr的回调
INTERFACES_MESSAGE_DECLARE_STREAM(onExecuteRawDatabaseCommandCB, NETWORK_VARIABLE_MESSAGE)
NETWORK_INTERFACE_DECLARE_END()
#ifdef DEFINE_IN_INTERFACE
#undef DEFINE_IN_INTERFACE
#endif
}
#endif // KBE_INTERFACES_TOOL_INTERFACE_H
看到这些是不是头疼呢?那我还原一个大家看看:
namespace LoginappInterface {
extern Network::MessageHandlers messageHandlers;
//Loginapp reqCreateAccount
pLoginappreqCreateAccount_exposed=messageHandlers.pushExposedMessage(Loginapp::reqCreateAccount);
}
还原之后都是这样的格式了,那么做了什么了啊,定义了全局的MessageHandlers ,让后吧这些消息都加入到相应的消息容器里面你,后面就知道了原来消息需要在这里添加了如果c++实现的话,那是不是这样呢后面验证;
好了,消息这部分搞的差不多了,现在我们看看main这部分同样还原一下代码:
kbeMain(int argc, char* argv[]);
int main(int argc, char* argv[])
{
loadConfig();
g_componentID = genUUID64();
parseMainCommandArgs(argc, argv);
char dumpname[MAX_BUF] = {0};
kbe_snprintf(dumpname, MAX_BUF, "%" PRAppID, g_componentID);
KBEngine::exception::installCrashHandler(1, dumpname);
int retcode = -1;
THREAD_TRY_EXECUTION;
retcode = kbeMain(argc, argv);
THREAD_HANDLE_CRASH;
return retcode;
}
int kbeMain(int argc, char* argv[])
{
ENGINE_COMPONENT_INFO& info = g_kbeSrvConfig.getLoginApp();
return kbeMainT<Loginapp>(argc, argv, LOGINAPP_TYPE, info.externalPorts_min,
info.externalPorts_max, info.externalInterface, 0, info.internalInterface);
}
这样还原出来,大家不用我说就知道这个是干嘛的了,主要的逻辑还是在KbeMainT这个函数里,
这个函数仔细阅读之后发现在windows下主要是初始化了网络接口,任务系统的构建,初始化,出事话线程池,加载python脚本等等,这些细节在思维导图中阅读,主要提到的是app的住循环部分:
看到了主要是在这里干事的,
在这里处理了任务,定时器,遍历selecet事件等,
好了 loginapp的住逻辑就说到这里,后面的思维导图可以仔细阅读,描述了大多的逻辑细节,下一节仔细说一下loginapp的主要通信逻辑细节。
如若转载请附上出处谢谢
思维导图地址:链接:https://pan.baidu.com/s/1jcWKQ1H3jnk9C4O2NUpV_A
提取码:6eu5
复制这段内容后打开百度网盘手机App,操作更方便哦