大侠们unity怎么在lua中用xlua protobuff的

拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(38d19a76d7c1663a-ua98).
重新安装浏览器,或使用别的浏览器cocos2d-x lua 中使用protobuf并对http进行处理
时间: 11:55:14
&&&& 阅读:76
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&
cocos2d-x lua 中使用protobuf并对http进行处理
本文介绍 cocos2d-x lua 中使用http 和 基于cocos2d-x 对lua http的封装(部分ok)
本博客链接
protobuf &Google的一个非常好用的数据传输的封装 说实话Google的东西确实比較好用 所以我们前后端数据交换就用他了 只是Google没有对lua进行支持 还好社区有开源的大侠们贡献 找了全部关于lua protobuf 我仅仅找到 云风的 pbc 改动相关cocos2d-x中的类能够正常使用。protoc-gen-lua 我在使用的时候 总是报截断数据 在改动后cocs2d-x中的类之后没有对protoc-gen-lua 进行測试是否是这个问题导致
1)集成 云风 云大侠的()&标准c写的protobuf 详细看pbc的帮助非常轻松集成
2) 生成pb文件(我自己写了个mac中批处理生成全部.proto文件为.pb文件)把pb 和proto文件都增加到项目资源中
#pb = "pb"
for i in *.proto
#echo ${i%.*}".pb"
#echo ${i%.*}
#pbn = $i | cut -d.
pbname=${i%.*}".pb"
#echo $pbn
#echo $pbname
protoc --descriptor_set_out $pbname $i
echo "finish"
也能够用命令行手动生成
protoc --descriptor_set_out aaa.pb aaa.proto3)本步骤能够忽略了,能够直接用io进行读取(Android是路径问题请看本文最以下解释)在lua中使用例如以下代码(我用的是cocos2d-x中绑定的CCFileUtils中的获取文件的方式,只是要手动用tolua++进行绑定到lua,能够參考我上个,云大侠中的
用lua io形式获取在相关了解中不能跨平台全部就用这个了)local protobuf = require "protobuf"
local buffer = CCFileUtils:sharedFileUtils():getFileData("entity/p_result.pb","r",0)
-- print(buffer)
protobuf.register(buffer)4)本步骤能够忽略了。能够直接用io进行读取(Android是路径问题请看本文最以下解释)&上一步完毕后我们要对提到的CCFileUtils.cpp中的类进行改动 假设不改动读文件pb文件会时好时坏 原因是 读文件的时候结束总是加入多余字节我也不清楚这个问题 进行改动cocos2d-x中CCFileUtils.cpp的以下方法中的读取数据后处理并在tolua++
中加入以下方法绑定到lua层
改动CCFileUtils.cp getFileData(const
char* pszFileName, const char* pszMode,unsignedlong * pSize)方法(在最后加入\0。保证字节不多余)例如以下代码
unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize)
unsigned char * pBuffer = NULL;
CCAssert(pszFileName != NULL && pSize != NULL && pszMode != NULL, "Invalid parameters.");
*pSize = 0;
// read the file from hardware
std::string fullPath = fullPathForFilename(pszFileName);
FILE *fp = fopen(fullPath.c_str(), pszMode);
CC_BREAK_IF(!fp);
fseek(fp,0,SEEK_END);
*pSize = ftell(fp);
fseek(fp,0,SEEK_SET);
pBuffer = new unsigned char[*pSize];
*pSize = fread(pBuffer,sizeof(unsigned char), *pSize,fp);
fclose(fp);
} while (0);
if (*pSize &0 && pBuffer[*pSize] != ‘\0‘)
pBuffer[*pSize] = ‘\0‘;
if (! pBuffer)
std::string msg = "Get data from file(";
msg.append(pszFileName).append(") failed!");
CCLOG("%s", msg.c_str());
5)经过上一步骤lua层基本搞定能够创建本地的数据并encode成数据传输到server端了 例如以下代码
local major = {
majorId = "795f94a9--bf16-043ba8081fab"
local buffer = protobuf.encode("com.sj.web.proto.Major", major)6)我们client传输数据到server端 server端会返回数据给我们 相同我们接收的数据肯定也是protobuf数据了 用 protobuf.decode进行解数据local t = protobuf.decode("com.sj.web.proto.Result", request:getResponseString())--tolua.cast(event.dataCString))--tolua.cast(event.dataCString,"CCString"):getCString())
print(t.major.gender)
print(t.major.majorId)
print(t.user.username)7)上一步中的数据是server端过来的数据。只是在http连接方面遇到了些小插曲
&(1)我先前用的是quick-cocos2d-x-lua中封装的CCHTTPRequest的这个进行server端交互 只是不如愿 由于server端过来的数据中是protobuf进行处理过的数据 在进行调试跟踪后发现过来的数据中不定什么地方都有\0结束符 这个导致直接在lua中调研CCHTTPRequest中的获取string 方法数据被截断不能正常解析 我在CCHTTPRequest::getResponseString进行处理过来的数据处理掉\0 也不行
(2)因为项目中要用的短连接socket我先前已经集成好luasocket。事实上这个开源的socket非常好用 也有对http的支持果断用这个測试下server端回来的数据 让我小小喜悦了一下 丢到protobuf.decode中进行解析正是我要的数据 只是有个不好的地方 luasocket对socket有设置一个超时时间 就能够不堵塞线程 可是htpp方式我找遍了站点上的资料也没找到非堵塞式的 只是这个没关系比較能够正常跑protobuf了 集成一个线程框架就ok了呀 能够用协同线程 或者是lua
llthreads 自己选择吧假设要用 luasocket的http 先附上luasocket的http代码
local http = require ‘socket.http‘
local ltn12 = require ‘ltn12‘
response_body = ""
request_body = ""
function http.post(u)
local t = {}
local r, c, h = http.request{
method = "POST",
headers = {
["Content-Type"] = "application/x-protobuf",
["Content-Length"] = #request_body,
source = ltn12.source.string(request_body),
sink = ltn12.sink.table(t)}
return r, c, h, t
-- url = ""
r,c,h,body=http.post(HTTP_URL)
if c~= 200 then
local protobuf = require "protobuf"
local buffer = CCFileUtils:sharedFileUtils():getFileData("entity/p_result_test.pb","r",0)
-- print(buffer)
protobuf.register(buffer)
local t = protobuf.decode("com.sj.web.proto.Result", body[1])
(3)只是我没实用上面中提到的luasocket http 个人感觉还是直接用coco2d-x中的CCHttpClient比較好用也不用处理线程的东西 由于我通过这个測试过c++层中protobuf进行解析是全然没问题的所以我就模仿(1)中提到的CCHTTPRequest对cocos2d::extension::CCHttpClient封装使用只是有点不顺利数据传到lua层还是不正常。我就进行对\0 进行处理
又让我喜悦了 处理获取的server数据例如以下std::vector&char& *data = response-&getResponseData();
for(int i=0;i&data-&size();i++){
//if ((*data)[i] != ‘\0‘) {
mystream && (*data)[i];
mystream && ‘\b‘;
mResponseData = mystream.str();
std::cout && mystream.str() && std::
CCLog("ddd:%s",mystream.str().c_str());
CCString * cstr = CCString::create(temp);
com::sj::web::proto::Result *r = new com::sj::web::proto::Result::Result();
r-&ParseFromString(temp.c_str());
CCLog("ParseFromString:::::::::%d
%s",r-&resultcode(),r-&release_major()-&majorcode().c_str());
CCLuaValueD
dict["request"] = CCLuaValue::ccobjectValue(this, "HTTPRequest");
dict["data"] = CCLuaValue::stringValue(mystream.str()); // 传值回到lua层
dict["dataCString"] = CCLuaValue::ccobjectValue(cstr, "CCString");
dict["dddd"] = CCLuaValue::stringValue("dssddsdsds");
LUA_FUNCTION listener = (LUA_FUNCTION)response-&getHttpRequest()-&getUserData();
CCLuaStack *stack = CCLuaEngine::defaultEngine()-&getLuaStack();
stack-&clean();
stack-&pushCCLuaValueDict(dict);
做好上一步进行改动cocos2d-x CCLuaStack.cpp 方法pushCCLuaValue(....) 中 代码293行代码。改动例如以下(这样做能够直接使用&lua_pushlstring(m_state, stringValue, length) 把全部数据压到lua上层)
return pushString(value.stringValue().c_str(), value.stringValue().length());
完整方法代码为:void CCLuaStack::pushCCLuaValue(const CCLuaValue& value)
const CCLuaValueType type = value.getType();
if (type == CCLuaValueTypeInt)
return pushInt(value.intValue());
else if (type == CCLuaValueTypeFloat)
return pushFloat(value.floatValue());
else if (type == CCLuaValueTypeBoolean)
return pushBoolean(value.booleanValue());
else if (type == CCLuaValueTypeString)
return pushString(value.stringValue().c_str(), value.stringValue().length()); //pushString(value.stringValue().c_str());
else if (type == CCLuaValueTypeDict)
pushCCLuaValueDict(value.dictValue());
else if (type == CCLuaValueTypeArray)
pushCCLuaValueArray(value.arrayValue());
else if (type == CCLuaValueTypeCCObject)
pushCCObject(value.ccobjectValue(), value.getCCObjectTypename().c_str());
好了就介绍到这里吧希望对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)读不到文件&
--其它平台
local filePath = CCFileUtils:sharedFileUtils():fullPathForFilename("entity/p_result.pb")
local addr = io.open(filePath,"rb")
protobuffer = addr:read "*a"
addr:close()
protobuf.register(protobuffer
-- android例如以下
local filePath = callJava()
local addr = io.open(filePath,"rb")
protobuffer = addr:read "*a"
addr:close()
protobuf.register(protobuffer)
近期Google产品及服务全面禁封 表示对国内互联网管控的表示吐槽&可是好的技术成果是无界的(我对protobuf的使用一如既往。如有想用的。请代理去下载吧) 对protobuf的使用总结
1)发现传输数据上字节上特别节省轻量,从这个优势上传输速度明显快过其它如json,尤其适合游戏通信,假设是考虑到用户通信流量及带宽资源节省问题能够考虑
2)一点不好就是客户输出数据不全预计是pbc反序列化优化table对象问题 (和后端交互数据全靠java写的小client日志输出查看,仅仅是为了方便查看后端返回数据) 然后回lua项目进行处理信息
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!cocos2d-x lua 中使用protobuf并对http进行处理 | 红颜丽人
cocos2d-x lua 中使用protobuf并对http进行处理
本文介绍 cocos2d-x lua 中使用http 和 基于cocos2d-x 对lua http的封装(部分ok)
本博客链接
Google的一个很好用的传输数据的封装 说实话Google的东西确实比较好用 所以我们前后端数据交换就用他了 不过Google没有对lua进行支持 还好社区有开源的大侠们贡献 找了所有关于lua protobuf 我只找到 云风的 pbc 修改相关cocos2d-x中的类可以正常使用。protoc-gen-lua 我在使用的时候 总是报截断数据 在修改后cocs2d-x中的类之后没有对protoc-gen-lua 进行测试是否是这个问题导致
1)集成 云风 云大侠的() 标准c写的protobuf 具体看pbc的帮助很轻松集成
2) 生成pb文件(我自己写了个mac中批处理生成所有.proto文件为.pb文件)把pb 和proto文件都加入到项目资源中
#pb = ”pb”
for i in *.proto
#echo ${i%.*}”.pb”
#echo ${i%.*}
#pbn = $i | cut -d.
pbname=${i%.*}”.pb”
#echo $pbn
#echo $pbname
protoc –descriptor_set_out $pbname $i
echo ”finish”
也可以用命令行手动生成
protoc –descriptor_set_out aaa.pb aaa.proto
3)本步骤可以忽略了,可以直接用io进行读取(Android是路径问题请看本文最下面解释)在lua中使用如下代码(我用的是cocos2d-x中绑定的CCFileUtils中的获取文件的方式,不过要手动用tolua++进行绑定到lua,可以参考我上个,云大侠中的 用lua io形式获取在相关了解中不能跨平台所有就用这个了)
[javascript]
local protobuf = require ”protobuf”
local buffer = CCFileUtils:sharedFileUtils():getFileData(“entity/p_result.pb”,”r”,0)
– print(buffer)
protobuf.register(buffer)
4)本步骤可以忽略了,可以直接用io进行读取(Android是路径问题请看本文最下面解释) 上一步完成后我们要对提到的CCFileUtils.cpp中的类进行修改 如果不修改读文件pb文件会时好时坏 原因是 读文件的时候结束总是添加多余字节我也不清楚这个问题 进行修改cocos2d-x中CCFileUtils.cpp的下面方法中的读取数据后处理并在tolua++ 中添加下面方法绑定到lua层
修改CCFileUtils.cp getFileData(const char* pszFileName, const char* pszMode,unsignedlong * pSize)方法(在最后添加\0,保证字节不多余)如下代码
unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize)
unsigned char * pBuffer = NULL;
CCAssert(pszFileName != NULL && pSize != NULL && pszMode != NULL, ”Invalid parameters.”);
*pSize = 0;
// read the file from hardware
std::string fullPath = fullPathForFilename(pszFileName);
FILE *fp = fopen(fullPath.c_str(), pszMode);
CC_BREAK_IF(!fp);
fseek(fp,0,SEEK_END);
*pSize = ftell(fp);
fseek(fp,0,SEEK_SET);
pBuffer = new unsigned char[*pSize];
*pSize = fread(pBuffer,sizeof(unsigned char), *pSize,fp);
fclose(fp);
} while (0);
if (*pSize &0 && pBuffer[*pSize] != *)
pBuffer[*pSize] = *;
if (! pBuffer)
std::string msg = ”Get data from file(“;
msg.append(pszFileName).append(“) failed!”);
CCLOG(“%s”, msg.c_str());
5)经过上一步骤lua层基本搞定可以创建本地的数据并encode成传输数据到服务器端了 如下代码
[javascript]
local major = {
majorId = &#a9--bf16-043ba8081fab”
local buffer = protobuf.encode(“com.sj.web.proto.Major”, major)
6)我们客户端数据传输到服务器端 服务器端会返回数据给我们 同样我们接收的数据肯定也是protobuf数据了 用 protobuf.decode进行解数据
[javascript]
local t = protobuf.decode(“com.sj.web.proto.Result”, request:getResponseString())–tolua.cast(event.dataCString))–tolua.cast(event.dataCString,”CCString”):getCString())
print(t.major.gender)
print(t.major.majorId)
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代码
[javascript]
local http = require ’socket.http’
local ltn12 = require ’ltn12′
response_body = ”"
request_body = ”"
function http.post(u)
local t = {}
local r, c, h = http.request{
method = ”POST”,
headers = {
["Content-Type"] = ”application/x-protobuf”,
["Content-Length"] = #request_body,
source = ltn12.source.string(request_body),
sink = ltn12.sink.table(t)}
return r, c, h, t
– url = ””
r,c,h,body=http.post(HTTP_URL)
if c~= 200 then
local protobuf = require ”protobuf”
local buffer = CCFileUtils:sharedFileUtils():getFileData(“entity/p_result_test.pb”,”r”,0)
– print(buffer)
protobuf.register(buffer)
local t = protobuf.decode(“com.sj.web.proto.Result”, body[1])
(3)不过我没有用上面中提到的luasocket http 个人感觉还是直接用coco2d-x中的CCHttpClient比较好用也不用处理线程的东西 因为我通过这个测试过c++层中protobuf进行解析是完全没问题的所以我就模仿(1)中提到的CCHTTPRequest对cocos2d::extension::CCHttpClient封装使用不过有点不顺利数据传到lua层还是不正常,我就进行对\0 进行处理 又让我喜悦了 处理获取的服务器数据如下
std::vector&char& *data = response-&getResponseData();
for(int i=0;i&data-&size();i++){
//if ((*data)[i] != *) {
mystream && (*data)[i];
mystream && ’\b’;
mResponseData = mystream.str();
std::cout && mystream.str() && std::
CCLog(“ddd:%s”,mystream.str().c_str());
CCString * cstr = CCString::create(temp);
com::sj::web::proto::Result *r = new com::sj::web::proto::Result::Result();
r-&ParseFromString(temp.c_str());
CCLog(“ParseFromString:::::::::%d
%s”,r-&resultcode(),r-&release_major()-&majorcode().c_str());
CCLuaValueD
dict["request"] = CCLuaValue::ccobjectValue(this, ”HTTPRequest”);
dict["data"] = CCLuaValue::stringValue(mystream.str()); // 传值回到lua层
dict["dataCString"] = CCLuaValue::ccobjectValue(cstr, ”CCString”);
dict["dddd"] = CCLuaValue::stringValue(“dssddsdsds”);
LUA_FUNCTION listener = (LUA_FUNCTION)response-&getHttpRequest()-&getUserData();
CCLuaStack *stack = CCLuaEngine::defaultEngine()-&getLuaStack();
stack-&clean();
stack-&pushCCLuaValueDict(dict);
做好上一步进行修改cocos2d-x CCLuaStack.cpp 方法pushCCLuaValue(….) 中 代码293行代码,修改如下(这样做可以直接使用 lua_pushlstring(m_state, stringValue, length) 把所有数据压到lua上层)
return pushString(value.stringValue().c_str(), value.stringValue().length());
完整方法代码为:
void CCLuaStack::pushCCLuaValue(const CCLuaValue& value)
const CCLuaValueType type = value.getType();
if (type == CCLuaValueTypeInt)
return pushInt(value.intValue());
else if (type == CCLuaValueTypeFloat)
return pushFloat(value.floatValue());
else if (type == CCLuaValueTypeBoolean)
return pushBoolean(value.booleanValue());
else if (type == CCLuaValueTypeString)
return pushString(value.stringValue().c_str(), value.stringValue().length()); //pushString(value.stringValue().c_str());
else if (type == CCLuaValueTypeDict)
pushCCLuaValueDict(value.dictValue());
else if (type == CCLuaValueTypeArray)
pushCCLuaValueArray(value.arrayValue());
else if (type == CCLuaValueTypeCCObject)
pushCCObject(value.ccobjectValue(), value.getCCObjectTypename().c_str());
好了就介绍到这里吧希望对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)读不到文件
[javascript]
–其他平台
local filePath = CCFileUtils:sharedFileUtils():fullPathForFilename(“entity/p_result.pb”)
local addr = io.open(filePath,”rb”)
protobuffer = addr:read ”*a”
addr:close()
protobuf.register(protobuffer
– android如下
local filePath = callJava()
local addr = io.open(filePath,”rb”)
protobuffer = addr:read ”*a”
addr:close()
protobuf.register(protobuffer)
最近Google产品及服务全面禁封 表示对国内互联网管控的表示吐槽 但是好的技术成果是无界的(我对protobuf的使用一如既往,如有想用的,请代理去下载吧) 对protobuf的使用总结
1)发现数据传输上字节上特别节省轻量,从这个优势上传输速度明显快过其他如json,尤其适合游戏通信,如果是考虑到用户通信流量及带宽资源节省问题可以考虑
2)一点不好就是客户输出数据不全估计是pbc反序列化优化table对象问题 (和后端交互数据全靠java写的小客户端日志输出查看,只是为了方便查看后端返回数据) 然后回lua项目进行处理信息
本文链接地址:
本条目发布于 。属于
分类。作者是 。Unity3D插件使用交流版
帖子:2683

我要回帖

更多关于 cocos lua protobuf 的文章

 

随机推荐