cocos2d-x lua 中使用protobuf并对http进行处理

cocos2d-x lua中使用protobuf并对http进行处理

本文介绍 cocos2d-x lua 中使用http 和 基于cocos2d-x 对lua http的封装(部分ok)

本博客链接

http://www.jb51.cc/article/p-uzwmdzfc-qn.html

protobuf Google的一个很好用的传输数据的封装 说实话Google的东西确实比较好用 所以我们前后端数据交换就用他了 不过Google没有对lua进行支持 还好社区有开源的大侠们贡献 找了所有关于lua protobuf 我只找到 云风的 pbc 修改相关cocos2d-x中的类可以正常使用。protoc-gen-lua 我在使用的时候 总是报截断数据 在修改后cocs2d-x中的类之后没有对protoc-gen-lua 进行测试是否是这个问题导致

1)集成 云风 云大侠的(博客lua-pbc标准c写的protobuf 具体看pbc的帮助很轻松集成

2) 生成pb文件(我自己写了个mac中批处理生成所有.proto文件为.pb文件)把pb 和proto文件都加入到项目资源中

[objc] view plain copy
  1. #!/bin/sh
  2. #pb="pb"
  3. foriin*.proto
  4. do
  5. #echo$i
  6. #echo${i%.*}".pb"
  7. #echo${i%.*}
  8. #pbn=$i|cut-d.
  9. pbname=${i%.*}".pb"
  10. #echo$pbn
  11. #echo$pbname
  12. protoc--descriptor_set_out$pbname$i
  13. done
  14. echo"finish"

也可以用命令行手动生成

[cpp]
    protoc--descriptor_set_outaaa.pbaaa.proto
3) 本步骤可以忽略了,可以直接用io进行读取(Android是路径问题请看本文最下面解释) 在lua中使用如下代码(我用的是cocos2d-x中绑定的CCFileUtils中的获取文件的方式,不过要手动用tolua++进行绑定到lua,可以参考我上个文章中的绑定方式,云大侠中的 用lua io形式获取在相关了解中不能跨平台所有就用这个了)
[javascript]
    localprotobuf=require"protobuf"
  1. localbuffer=CCFileUtils:sharedFileUtils():getFileData("entity/p_result.pb","r",0)
  2. --print(buffer)
  3. protobuf.register(buffer)
4) 本步骤可以忽略了,可以直接用io进行读取(Android是路径问题请看本文最下面解释) 上一步完成后我们要对提到的CCFileUtils.cpp中的类进行修改 如果不修改读文件pb文件会时好时坏 原因是 读文件的时候结束总是添加多余字节我也不清楚这个问题 进行修改cocos2d-xCCFileUtils.cpp的下面方法中的读取数据后处理并在tolua++ 中添加下面方法绑定到lua层

修改CCFileUtils.cp getFileData(constchar* pszFileName,constchar* pszMode,unsignedlong* pSize)方法(在最后添加\0,保证字节不多余)如下代码

    unsignedchar*CCFileUtils::getFileData(constchar*pszFileName,char*pszMode,unsignedlong*pSize)
  1. {
  2. unsignedchar*pBuffer=NULL;
  3. CCAssert(pszFileName!=NULL&&pSize!=NULL&&pszMode!=NULL,"Invalidparameters.");
  4. *pSize=0;
  5. {
  6. //readthefilefromhardware
  7. std::stringfullPath=fullPathForFilename(pszFileName);
  8. FILE*fp=fopen(fullPath.c_str(),pszMode);
  9. CC_BREAK_IF(!fp);
  10. fseek(fp,SEEK_END);
  11. *pSize=ftell(fp);
  12. fseek(fp,SEEK_SET);
  13. pBuffer=newunsignedchar[*pSize];
  14. *pSize=fread(pBuffer,sizeof(unsignedchar),*pSize,fp);
  15. fclose(fp);
  16. }while(0);
  17. if(*pSize>0&&pBuffer[*pSize]!='\0')
  18. pBuffer[*pSize]='\0';
  19. if(!pBuffer)
  20. std::stringmsg="Getdatafromfile(";
  21. msg.append(pszFileName).append(")failed!");
  22. CCLOG("%s",msg.c_str());
  23. }
  24. returnpBuffer;
  25. }

5)经过上一步骤lua层基本搞定可以创建本地的数据并encode成传输数据到服务器端了 如下代码

    localmajor={
  1. majorId="795f94a9-3466-41b4-bf16-043ba8081fab"
  2. }
  3. localbuffer=protobuf.encode("com.sj.web.proto.Major",major)
6)我们客户端数据传输到服务器端 服务器端会返回数据给我们 同样我们接收的数据肯定也是protobuf数据了 用 protobuf.decode进行解数据
    localt=protobuf.decode("com.sj.web.proto.Result",request:getResponseString())--tolua.cast(event.dataCString))--tolua.cast(event.dataCString,"CCString"):getCString())
  1. cclog(t)
  2. print(t.major.gender)
  3. print(t.major.majorId)
  4. print(t.user.username)
7)上一步中的数据是服务器端过来的数据,不过在http连接方面遇到了些小插曲

(1)我先前用的是quick-cocos2d-x-lua中封装的CCHTTPRequest的这个进行服务器端交互 不过不如愿 因为服务器端过来的数据中是protobuf进行处理过的数据 在进行调试跟踪后发现过来的数据中不定什么地方都有\0结束符 这个导致直接在lua中调研CCHTTPRequest中的获取string 方法数据被截断不能正常解析 我在CCHTTPRequest::getResponseString进行处理过来的数据处理掉\0 也不行

(2)由于项目中要用的短连接socket我先前已经集成好luasocket,其实这个开源的socket很好用 也有对http的支持果断用这个测试下服务器端回来的数据 让我小小喜悦了一下 丢到protobuf.decode中进行解析正是我要的数据 不过有个不好的地方 luasocket对socket有设置一个超时时间 就可以不阻塞线程 但是htpp方式我找遍了网站上的资料也没找到非阻塞式的 不过这个没关系比较可以正常跑protobuf了 集成一个线程框架就ok了呀 可以用协同线程 或者是lua llthreads 自己选择吧如果要用 luasocket的http 先附上luasocket的http代码

    localhttp=require'socket.http'
  1. localltn12=require'ltn12'
  2. response_body=""
  3. request_body=""
  4. functionhttp.post(u)
  5. localt={}
  6. localr,c,h=http.request{
  7. url=u,
  8. method="POST",
  9. headers={
  10. ["Content-Type"]="application/x-protobuf",108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> ["Content-Length"]=#request_body,
  11. },
  12. source=ltn12.source.string(request_body),248)"> sink=ltn12.sink.table(t)}
  13. returnr,h,t
  14. end
  15. --url="http://www.baidu.com"
  16. r,body=http.post(HTTP_URL)
  17. print(c)
  18. ifc~=200then
  19. return
  20. end
  21. localprotobuf=require"protobuf"
  22. localbuffer=CCFileUtils:sharedFileUtils():getFileData("entity/p_result_test.pb",0)
  23. --print(buffer)
  24. protobuf.register(buffer)
  25. localt=protobuf.decode("com.sj.web.proto.Result",body[1])
  26. cclog(t)

(3)不过我没有用上面中提到的luasocket http 个人感觉还是直接用coco2d-x中的CCHttpClient比较好用也不用处理线程的东西 因为我通过这个测试过c++层中protobuf进行解析是完全没问题的所以我就模仿(1)中提到的CCHTTPRequest对cocos2d :: extension :: CCHttpClient封装使用不过有点不顺利数据传到lua层还是不正常, 我就进行对\0 进行处理 又让我喜悦了 处理获取的服务器数据如下
    std::vector<char>*data=response->getResponseData();
  1. std::stringstreammystream;
  2. for(inti=0;i<data->size();i++){
  3. //if((*data)[i]!='\0'){
  4. mystream<<(*data)[i];
  5. //}else{
  6. //mystream<<'\b';
  7. //}
  8. mResponseData=mystream.str();
  9. std::cout<<mystream.str()<<std::endl;
  10. CCLog("ddd:%s",mystream.str().c_str());
  11. CCString*cstr=CCString::create(temp);
  12. //com::sj::web::proto::Result*r=newcom::sj::web::proto::Result::Result();
  13. //r->ParseFromString(temp.c_str());
  14. //CCLog("ParseFromString:::::::::%d%s",r->resultcode(),r->release_major()->majorcode().c_str());
  15. CCLuaValueDictdict;
  16. dict["request"]=CCLuaValue::ccobjectValue(this,"HTTPRequest");
  17. dict["data"]=CCLuaValue::stringValue(mystream.str());//传值回到lua层
  18. dict["dataCString"]=CCLuaValue::ccobjectValue(cstr,"CCString");
  19. dict["dddd"]=CCLuaValue::stringValue("dssddsdsds");
  20. LUA_FUNCTIONlistener=(LUA_FUNCTION)response->getHttpRequest()->getUserData();
  21. CCLuaStack*stack=CCLuaEngine::defaultEngine()->getLuaStack();
  22. stack->clean();
  23. stack->pushCCLuaValueDict(dict);

做好上一步进行修改cocos2d-x CCLuaStack.cpp 方法pushCCLuaValue(....) 中 代码293行代码,修改如下(这样做可以直接使用lua_pushlstring(m_state,stringValue,length) 把所有数据压到lua上层)

    returnpushString(value.stringValue().c_str(),value.stringValue().length());

完整方法代码为:
    voidCCLuaStack::pushCCLuaValue(constCCLuaValue&value)
  1. constCCLuaValueTypetype=value.getType();
  2. if(type==CCLuaValueTypeInt)
  3. returnpushInt(value.intValue());
  4. elseif(type==CCLuaValueTypeFloat)
  5. returnpushFloat(value.floatValue());
  6. if(type==CCLuaValueTypeBoolean)
  7. returnpushBoolean(value.booleanValue());
  8. if(type==CCLuaValueTypeString)
  9. //pushString(value.stringValue().c_str());
  10. if(type==CCLuaValueTypeDict)
  11. pushCCLuaValueDict(value.dictValue());
  12. if(type==CCLuaValueTypeArray)
  13. pushCCLuaValueArray(value.arrayValue());
  14. if(type==CCLuaValueTypeCCObject)
  15. pushCCObject(value.ccobjectValue(),value.getCCObjectTypename().c_str());
  16. }

好了就介绍到这里吧希望对cocos2d-x lua 开发的同行们有所帮助 如果有什么好的protobuf对cocos2d-x lua的支持 或者是更方便的集成 也请贡献给我一份哟 谢谢

本人用风云的pbc 心得 总的来说还算可以

1)浮点类型:java—>lua 没问题;lua—>java 没通过。我们后端用的java 估计是lua对number浮点数类型进行decode的 有整形进行传递的时候导致没有进行对浮点类型转换(或者java对类型比较严格导致解码的时候对高地位转换失败所致) 由于开发效率前后端改成string进行传递(测试过protoc-gen-lua 也有这个问题)如有朋友能使用lua—>java进行浮点类型通信OK 迫切滴希望您共享我一份解决方案

2)枚举类型 proto文件中序号从1开始计数 否则pbc pb文件加载失败

3)上面提到的加载pb文件的时候ios win 也可以根据 CCFileUtils获取pb文件路径后用 lua io进行注册,测试android(我还是用上面提到的方法进行读文件)用这种方式没成功 应该是路径和权限问题导致(已经验证过是android中读取文件路径问题,我的方式是把proto写到本地后lua用io进行读取ok)读不到文件

    --其他平台
  1. localfilePath=CCFileUtils:sharedFileUtils():fullPathForFilename("entity/p_result.pb")
  2. localaddr=io.open(filePath,"rb")
  3. protobuffer=addr:read"*a"
  4. addr:close()
  5. protobuf.register(protobuffer
  6. --android如下
  7. localfilePath=callJava()
  8. protobuf.register(protobuffer)

最近Google产品及服务全面禁封 表示对国内互联网管控的表示吐槽但是好的技术成果是无界的(我对protobuf的使用一如既往,如有想用的,请代理去下载吧) 对protobuf的使用总结

1)发现数据传输上字节上特别节省轻量,从这个优势上传输速度明显快过其他如json,尤其适合游戏通信,如果是考虑到用户通信流量及带宽资源节省问题可以考虑

2)一点不好就是客户输出数据不全估计是pbc反序列化优化table对象问题 (和后端交互数据全靠java写的小客户端日志输出查看,只是为了方便查看后端返回数据) 然后回lua项目进行处理信息


转载一些自己感觉好的文章,只是为了记录,以后查找方便,大家尽量去阅读原文。

原文地址:http://www.jb51.cc/article/p-uzwmdzfc-qn.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是