其他分享
首页 > 其他分享> > KBEngine 服务器端-loginapp-协议构建、解析执行详细介绍

KBEngine 服务器端-loginapp-协议构建、解析执行详细介绍

作者:互联网

宏宏宏

由于 C++ 是静态语言,不能像 js 一样通过函数名字符串来直接执行函数,所以将 messageId 映射到可执行函数的复杂性大大提升;KBEngine 使用了一系列精巧的「宏」来解决这个问题。

为了叙述方便,我把需要通过 messageId 来映射执行的函数称为「协议函数」,以区分普通的函数。

loginapp 的宏,统一在 loginapp_interface_macros.h 中声明,在 loginapp_interface.h 中使用。我把 loginapp_interface.h 进行简化,只保留两个函数:importClientMessage,login。

可以看到,上面截图分为 3 个部分

namespace LoginappInterface

上图是将本文第一张图 5、14 行宏展开后的代码,这对 BEGIN/END 宏,不光是定义了一个 namespace,更重要的是,声明了 messageHandlers,这里面就存放了所有映射好的「协议函数」

importClientMessages

上图是将本文第一张图中第 8 行展开后的代码,由几个重要的逻辑组成:

login

上图是将本文第一张图中第 11、12 行展开后的代码,由几个重要的逻辑组成:

MessageHandlers::add

add 函数,将"Loginapp::login" 形式的函数名转成 messageId,并与 MessageHandler* 建立映射关系。

上图,150~171 行,先通过 FixedMessage 判断("Loginapp::login")函数名是否在 res/server/messages_fixed.xml 中声明过,如果声明过,就取声明的 id 作为 messageId,否则就循环找到一个未被使用的 id。

上图,180 行建立 messageId 到 MessageHandler* 的映射。msgHandlers_ 是一个 map。

 

上图,50 行,可以看到 FixMessages 加载的配置文件地址,就是我们一直提到的 messages_fixed.xml。

协议执行

通过上面的宏,我们可以看到 messageId -> 「协议函数」的映射关系已经建立起来,那么这个在什么时候回被调用到呢?

上图是 login 函数的调用堆栈,我们来看一下 Loginapp::handleMainTick 函数

可以看到,112 行的参数是 &LoginappInterface::messageHandlers,也就是在宏里已经填好 messageId -> 「协议函数」映射关系的全局变量。

真正的执行逻辑,在 PacketReader::processMessages 函数里。

如上图,先在 81 行取到 messageId,然后在 85 行,在 messageHandlers 里 find (简单的 map 的查找即可)到对应的 MessageHandler,再调用 handle 函数,按我们前面的分析,handle 函数里面会调用到 messageId 对应的 「协议函数」。

至此,整个 loginapp 服务器端协议从构建到解析执行的整个过程解释完成。

后记

KBEngine 支持的几种宏说明

ltk80 发布了20 篇原创文章 · 获赞 10 · 访问量 2万+ 私信 关注

标签:协议,函数,映射,importClientMessages,loginapp,KBEngine,messageId,LOGINAPP,服务器端
来源: https://blog.csdn.net/ltk80/article/details/104423767