KBEngine 客户端-loginapp-协议加载

「登录」前需要加载通信协议,加载过程需要在服务器与客户端之间进行函数交互调用。

理清问题

这篇文章里,我们将要理清前文《阅读 KBEngine 要理清的问题》提到的问题

  • 服务器端与客户端是怎么交互的?

先给出结论,具体可看文章最后的「小结」

通过在服务器端和客户端分别解析 res/server/messages_fixed.xml 中声明的协议来完成交互。 其实就是分别构建 <messageId,回调函数> 键值对。
那么,客户端是怎么知道如何解析这个协议的呢?

我们接着上文《KBEngine Cocos2d JS 客户端启动过程》来一步步说明,上文最后提到,流程进入到 plugins/kbengine_js_plugins/kbengine.js 里的 login 函数。

kbengine.js / login

login 函数中,3086行参数为 true 来调用 login_loginapp,所以逻辑会进入 3093~3096 行,即使用 ws 协议访问在 main.js 里配置的 ip:port;在 connect 成功后的回调函数是 kbengins.js 中的 onOpenLoginapp_login。

ws 协议介绍,这里给出部分截图,便于理解。


kbengine.js / onOpenLoginapp_login

opOpenLoginapp_login 主要有几个逻辑:

  • 2600 行,设置 currentserver = 'loginapp'
  • 2601 行,设置 currentstate = 'login'
  • 2605~2610 行,访问服务器端的 loginapp::importClientMessages 函数,回调函数是 kbengins.js 中的 Client_onImportClientMessages 函数

为什么 2605~2607 行能访问到 loginapp 中的 importClientMessages 函数?

因为 2066 行, KBEngine.messages.Loginapp_importClientMessages 对应的 messageId 在 服务器端 loginapp 中的处理函数是 importClientMessage 函数。这个配对需要在客户端和服务器端都进行声明。

客户端在 kbengine.js 中声明了 Loginapp_importClientMessages 对应的 messageId = 5. 如下图所示:


服务器端在 res/server/messages_fixed.xml 中声明了 messageId = 5 对应的处理函数为 Loginapp 中 importClientMessage 函数。如下图所示:


loginapp.cpp / importClientMessages

服务器端的 loginapp.cpp 中的 importClientMessages 函数,向客户端发送协议信息。



有几个主要逻辑

  • 5~24 行,取所有 Client 中标为 Exposed 的协议
  • 26~47 行,取所有 Loginapp 中标为 Exposed 的协议
  • 49 行,设置发送回客户端的 messageId,这个与客户端的 messageId 要一致,下文有进一步说明。
  • 54~78 行,数据塞到流里
  • 81 行,发送到客户端
  • 17 行,回调函数名称,如 Loginapp::login 改为 Loginapp_login;这个很重要,这里定义了消息名称,客户端会拿这个来回调 loginapp 的函数

kbengine.js / Client_onImportClientMessages

由于前文设置了 onmessage = Client_onImportClientMessages,根据 ws 协议,服务器返回信息时,就会调用到这个函数。


Client_onImportClientMessages 有几个主要逻辑:

  • 2972 行,先判断读取到的 messageId 是否为 KBEngine.messages.onImportClientMessages,可见服务器也是以 messageId 来标识客户端的处理函数的。这里确实在服务器端和客户端都做了配对

    服务器端在 res/server/messages_fixed.xml 中声明了 messageId = 518 对应的处理函数为 客户端 中 importClientMessage 函数。如下图所示:

    客户端在 kbengine.js 中声明了 onImportClientMessages 对应的 messageId = 518. 如下图所示:
    服务器端是如何访问客户端的,将在讲解服务器端代码时说明。

  • 2983~3022行,代码先读取 msgid(2983行),然后看 msgname 是否带有 Client_(2996行)
    如果有,就是 Client 回调函数(即 kbengine.js 中的以 Client_ 开头的函数,loginapp 服务器往客户端发送协议时,就会把 messages_fixed.xml 中的声明 Client::xxx 改成 Client_xxx 作为函数名),就把 msgid -> Client_xxx 添加到 KBEngine.clientmessage 中;
    否则,就是服务器的函数,因为服务器分为 baseapp、loginapp 等,就要分别按 currserver 来存放,前面 (2600 行)设置了 currentserver ='loginapp',所以这里取到的,除去 client 之外,就是 loginapp 中的回调函数;
    至此,在客户端中加载 client 和 loginapp 中的协议完成。
  • 3026 行, Client_onImportClientMessages 的最后,会调用 onImportClientMessageCompleted 函数。

kbengine.js / onImportClientMessageCompleted 

onImportClientMessageCompleted 有几个逻辑:

  • 2643行,设置 socket.onmessage 为 app.onmessage
  • 2644 行,hello 函数 (握手,这个不属于协议加载,将在后面细讲)
  • 还记得前面 2600、2601 行设置的吧,此时 currentserver == 'loginapp',currstate == 'login',所以会执行到 2658 行,即此时才会真正开始发送用户名、密码进行登录。

kbengine.js / onmessage

前面可知,协议加载完成后,在 onImportClientMessageCompleted 里的 2643 行,会把 socket 的 onmessage 置为上图的 onmessage 函数。

逻辑很简单,就是取到  msgid,然后在 KBEngine.clientmessage 中取到相应的 handler,然后执行即可。由此,服务器端就可以调用到客户端的函数。

小结

抛开前面各种回调,我们来说明一下 KBEngine 的协议机制。为简化起见,这里只说明 loginapp 与 client 进行交互的协议。

  1. 在 res/server/messages_fixed.xml 中,以 <Client::xxx></Client::xxx> 的形式声明客户端将要提供的函数,以<Loginapp:xxx></Loginapp::xxx> 的形式声明 loginapp 将要提供的函数
  2. 客户端(这里是 kbengins.js)实现具体的函数
  3. loginapp 实现具体的函数
  4. loginapp 加载 message_fixed.xml 并解析,首先建立 <messageId, 3 中实现的函数>的映射关系,即此时客户端可以通过一个 messageId 调用到 loginapp 的函数;其次知道客户端有哪些函数可以被调用,这些函数的 messageId 分别是什么。
  5. 客户端没法直接加载 message_fixed.xml,只能通过 loginapp 来加载协议;
  6. 客户端在加载协议之前,不知道 loginapp 的返回协议的函数对应的 id;所以协议加载函数的 id 必须在客户端写死,也就是前面提到的 messageId = 5,这个 messageId 传到 loginapp 服务器之后,就能调到 Loginapp::importClientMessage 函数;并返回协议信息。
  7. 客户端拿到协议信息,首先建立 <messageId,2 中实现的函数>的映射关系,即此时 loginapp 服务器可以通过一个 messageId 调用到客户端的函数;其次,知道 loginapp 服务器端有哪些函数可以被调用,这些函数的 messageId 分别是什么。
  8. 至此,客户端和 loginapp 服务器端都分别建立起 <message,回调函数> 的映射关系,即协议构建成功
  9. 最后补充一下,服务器与客户端交互都是通过 MemoryStream 来传递数据,先传递 messageId,然后传递参数;
    客户端/loginapp 服务器端读取网络数据时,先读取到 messageId,就知道要调用哪个函数,然后就把后面的参数取出来,进行具体调用即可。
    客户端的这个过程,可以参看前面的 onmessage 函数。
    服务器的这个过程,请看后文《KBEngine 服务器端-loginapp-协议构建、解析执行
    》。

转载于:https://my.oschina.net/zenglingfan/blog/616930

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值