KBEngine官方论坛

 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 配置 开服
查看: 1411|回复: 0

导入服务器消息(C++的客户端插件一)

[复制链接]

41

主题

94

帖子

719

积分

高级会员

Rank: 4

积分
719
发表于 2015-10-30 13:36:44 | 显示全部楼层 |阅读模式
本帖最后由 bbydt 于 2015-10-30 13:40 编辑

首先要感谢 cnsoft ,还有就是unity原生提供的 插件,我在其基础上修改了
登录流程有一种情况就是,先创建账号,再进行登录,这里先分析下创建账号的过程,这里先看下导入服务器消息,已经客户端等待服务器返回消息的过程!
下面是用cocos作为客户端平台写的C++代码,其实可以跨平台的,主要就用了cocos 的打日志还有就是继承了ccobject 类。
KBEApplication.h  这个里面定义了类
  1. class ClientObjectBase
  2.         {
  3.         public:
  4.         ..........
  5.         };
复制代码
基类里面实现了全部的对于各种消息的处理的函数,用其子类进行操作
  1. class ClientApp :
  2.                 public ClientObjectBase
  3.         {
  4.         public:
  5.                 static ClientApp& getInstance()
  6.                 {
  7.                         static ClientApp instance;
  8.                         return instance;
  9.                 }
复制代码
到Coco工程里面,实现一个点击button的回调函数里面 ,里面参数就是 账号,密码,平台信息
  1. ClientApp::getInstance().createAccount("MacroGu", "123456", "ByMacroGu");
复制代码

下面是 createAccount函数的实现
  1. void ClientObjectBase::createAccount(std::string username, std::string password, std::string extradatas)
  2. {
  3.         printf("得到的 username:%s password:%s extradatas:%s", username.c_str(), password.c_str(), extradatas.c_str());
  4.         this->name_ = username;
  5.         this->password_ = password;
  6.         this->extradatas_ = extradatas;
  7.         
  8.         ClientApp::getInstance().createAccount_loginapp(true);
  9. }
复制代码
很明显,也是用的单例模式,到了函数 createAccount_loginapp,里面的参数true和false是安装登录进行的过程来填写的
  1. void  ClientObjectBase::createAccount_loginapp(bool noconnect)
  2. {
  3.         if (noconnect)
  4.         {
  5.         //        reset();
  6.                 KBEGameSocket::getInstance().connectionServer(ip_.c_str(), port_, &KBEngineClient::ClientObjectBase::onConnectTo_createAccount_callback, NULL);
  7.         }
  8.         else
  9.         {
  10.                 KBEngineClient::KBundle bundle;
  11.                 bundle.newmessage(*KMessage::messages["Loginapp_reqCreateAccount"]);
  12.                 bundle.writeString(name_);
  13.                 bundle.writeString(password_);
  14.         //        bundle.writeBlob((char*)extradatas_.c_str(), extradatas_.size());
  15.                 bundle.send(*pServerChannel_);
  16.         }
  17. }
复制代码
true表示还没有建立和服务器的连接,那肯定就是进入到建立连接的分支了,注意这里的connectionServer里面的第三个参数是回调函数,定义如下
  1. // 连接操作 connect 的回调函数定义
  2. typedef void(__stdcall *ConnectCallBack) (const char* ipStr, uint32 port , bool success, void* data);
复制代码
连接操作完成之后,自然就会进入到回调操作的函数里面,下面是其实现
  1. void _stdcall ClientObjectBase::onConnectTo_createAccount_callback(const char* ipStr, uint32 port, bool success, void* data)
  2. {
  3.         if (!success)
  4.         {
  5.                 printf("KBEngine::createAccount_loginapp(): connect {%s}:{%d} is error!", ipStr, port);
  6.                 return;
  7.         }

  8.         printf("KBEngine::createAccount_loginapp(): connect {%s}:{%d} is success!", ipStr, port);
  9.         
  10.         ClientApp::getInstance().onOpenLoginapp_createAccount();                // 只能这么用了
  11. }
复制代码
根据传入的bool参数,如果连接成功了,会进入到创建账号的流程,下面是 onOpenLoginapp_createAccount的实现
  1. void ClientObjectBase::onOpenLoginapp_createAccount()
  2. {
  3.         printf("KBEngine::onOpenLoginapp_createAccount: successfully!");
  4.         currserver = "loginapp";
  5.         currstate = "createAccount";

  6.         if (!loginappMessageImported_)
  7.         {
  8.                 KBundle* pBundle = new KBundle();
  9.                 (*pBundle).newmessage(*KMessage::messages["Loginapp_importClientMessages"]);
  10.                 pBundle->send(*pServerChannel_);
  11.         }
  12.         else
  13.         {
  14.                 onImportClientMessagesCompleted();
  15.         }
  16. }
复制代码
里面有个判断bool类型,这个类型,表示是否已经从服务器导入了loginapp的基本消息。这里有必要多说几句,消息头的定义,包括消息的名称什么的,都是定义在服务器的,客户端只是在登录的时候从服务器导入,这里开始时候判断到没有导入,那么就发消息进行导入
  1.   // 消息协议是否已经导入了
  2.                 bool loginappMessageImported_ = false;
复制代码
调试发现,导入消息的消息头的msgid是 518,那么我们在客户端的接收操作死循环中添加对消息518的出来过程。
  1.     if( msgid==518)
  2.                                 {
  3.                                         ClientApp::getInstance().onImportClientMessages(stream);
  4.                                         continue;
  5.                                         //how to check left data?
  6.                                 }
复制代码
下面是 onImportClientMessages 实现
  1. void ClientObjectBase::onImportClientMessages(MemoryStream& stream)
  2. {

  3.         uint16 msgcount;
  4.         stream >> msgcount;

  5.         printf("KBEngine::Client_onImportClientMessages: start({%d})...", msgcount);

  6.         while (msgcount > 0)
  7.         {
  8.                 msgcount--;

  9.                 MessageID msgid;
  10.                 stream >> msgid;
  11.                 int16 msglen;
  12.                 stream >> msglen;

  13.                 std::string msgname;
  14.                 stream >> msgname;

  15.                 int8 argstype;
  16.                 stream >> argstype;
  17.                 Byte argsize;
  18.                 stream >> argsize;
  19.                 //List<Byte> argstypes = new List<Byte>();
  20.                 Byte* argstypes = new Byte[argsize];
  21.                 for (Byte i = 0; i<argsize; i++)
  22.                 {
  23.                         //argstypes.Add(stream.readUint8());
  24.                         uint8 _tmp;
  25.                         stream >> _tmp;
  26.                         argstypes[i] = _tmp;
  27.                 }
  28.                 bool isClientMethod = msgname.find("Client_") == 0;

  29.                 if (isClientMethod)
  30.                 {
  31.                 }

  32.                 if (msgname.length() > 0)
  33.                 {
  34.                         int handler = 0;
  35.                         KMessage::messages[msgname] = new KMessage(msgid, (char*)msgname.c_str(), msglen, argstype, argstypes, 0);

  36.                         if (isClientMethod)
  37.                         {
  38.                                 KMessage::clientMessages[msgid] = KMessage::messages[msgname];
  39.                                 CCLOG("KBEngine::onImportClientMessages store {%s}  msgid:%d", msgname.c_str(),msgid);
  40.                         }
  41.                         else
  42.                         {
  43.                                 if (ip_ == "")
  44.                                         KMessage::loginappMessages[msgid] = KMessage::messages[msgname];
  45.                                 else
  46.                                         KMessage::baseappMessages[msgid] = KMessage::messages[msgname];
  47.                         }
  48.                 }
  49.                 else
  50.                 {
  51.                         //todo replace handler with real handle call back!
  52.                         KMessage* msg = new KMessage(msgid, (char*)msgname.c_str(), msglen, argstype, argstypes, NULL);

  53.                         currserver = "loginapp";

  54.                         if (ip_ != "")
  55.                                 currserver = "baseapp";
  56.                         //
  57.                         if (currserver == "loginapp")
  58.                                 KMessage::loginappMessages[msgid] = msg;
  59.                         else
  60.                                 KMessage::baseappMessages[msgid] = msg;
  61.                 }
  62.         };

  63.         onImportClientMessagesCompleted();
  64.         //Todo: send next packet. loginapp hello
  65.         //add by MacroGu: 这个 hello 的包,可能是发给loginapp 或者baseapp 的
  66. }
复制代码
导入完成就会到 onImportClientMessagesCompleted 函数中了,下面是该函数的实现
  1. void ClientObjectBase::onImportClientMessagesCompleted()
  2. {
  3.         // 从服务器导入 消息结束之后,会到此发消息,就是发生 hello 给服务器    主要不要多发消息,不同状态发送消息,服务器不进行处理,返回错误值,
  4.         // 客户端有可能会因为错误返回而断开和服务器的连接
  5.         // 完全借鉴 unity 里面的C#方法
  6.         printf("KBEngine::onImportClientMessagesCompleted: successfully! currserver:%s currstate:%s",currserver.c_str() ,currstate.c_str());
  7.         if (currserver == "loginapp")
  8.         {
  9. 。。。。。。。。。。。。。。。。。。
  10.                 else if (currstate == "createAccount")
  11.                 {
  12.                         createAccount_loginapp(false);
  13.                 }
  14.                 else{
  15.                 }

  16.                 loginappMessageImported_ = true;
  17.         }
  18.         else
  19.         {
  20.             。。。。。。。。。
  21.         return;
  22. }
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|KBEngine Forum

GMT+8, 2018-12-11 16:53 , Processed in 0.031241 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表