Cocos2d-x in Lua using PROTOBUF and processing HTTP

Source: Internet
Author: User
Tags lua

Cocos2d-x in Lua using PROTOBUF and processing HTTP

This article describes the use of HTTP and Cocos2d-x to LUA HTTP encapsulation (partially OK) in Cocos2d-x Lua

This blog link

http://blog.csdn.net/vpingchangxin/article/details/24458051

Protobuf Google's a very good use of the package to transmit data to tell the truth, Google's things are really easy to use, so we end data exchange with him, but Google did not support Lua. Fortunately, the community has open source heroes who have contributed to all the Lua PROTOBUF I only found Cloud Wind's PBC modify the classes in the related cocos2d-x to work properly. Protoc-gen-lua I always report the truncation of data when I'm using it. Cocs2d-x after the class in the modified Protoc-gen-lua is not tested for the problem caused

1) Integrated Cloud Master (blog) LUA-PBC standard C written protobuf specifically see the PBC help is easy to integrate

2 Generate PB file (I wrote a Mac myself batch generates all. proto files for. pb files) add both PB and proto files to the project resource

#!/bin/sh
#pb = "PB" for
i-*.proto
do
	#echo $i
	#echo ${i%.*} ". Pb"
	#echo ${i%.*}
	#pbn = $i | cut-d.
	pbname=${i%.*} ". Pb"
	#echo $pbn
	#echo $pbname
	protoc--descriptor_set_out $pbname
$i Done echo "Finish"

You can also manually build with the command line

Protoc--descriptor_set_out AAA.PB Aaa.proto
3 This step can be ignored, you can read directly with Io (Android is a path problem, see the bottom of this article) use the following code in LUA (I'm using the way to get files in the ccfileutils bound in Cocos2d-x, but manually tolua++ To be bound to Lua, you can refer to the bindings in my last article, which is used in the Lua IO form in the Cloud warrior to get across the platform in the relevant knowledge.
Local PROTOBUF = require "protobuf" local
    buffer = Ccfileutils:sharedfileutils (): Getfiledata ("ENTITY/P_RESULT.PB" , "R", 0)
    --Print (buffer)
    protobuf.register (buffer)
4 This step can be ignored, you can read directly with Io (Android is the path problem, please see the bottom of this article) we have to modify the class in the mentioned CCFileUtils.cpp if you do not modify the read-file PB file will be good when the bad reason is End of reading files always add extra bytes I'm not sure about this. Modify the read data in the following method of CCFileUtils.cpp in Cocos2d-x and add the following method to the LUA layer in tolua++

Modify the CCFILEUTILS.CP getfiledata (const char* pszfilename, const char* Pszmode, unsigned long * psize) method (at the end of the add, ensure that the bytes are not redundant) the following code

unsigned char* ccfileutils::getfiledata (const char* pszfilename, const char* Pszmode, unsigned long * psize) {Unsigne
    d char * pbuffer = NULL;
    Ccassert (pszfilename!= null && psize!= null && pszmode!= null, "Invalid parameters.");
    *psize = 0;
        Do {//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 ());
    return pbuffer; }

5 after the last step of the LUA layer basic finish can create local data and encode to the server side of the following code

Local major = {
        Majorid = ' 795f94a9-3466-41b4-bf16-043ba8081fab '
    } local
    buffer = Protobuf.encode (" Com.sj.web.proto.Major ", Major)
6 Our client data transfer to the server side of the server will be returned to us the same data we received must also be PROTOBUF data, using Protobuf.decode to solve data
Local T = Protobuf.decode ("Com.sj.web.proto.Result", Request:getresponsestring ())--tolua.cast (event.datacstring))- -tolua.cast (event.datacstring, "ccstring"): Getcstring ())
        Cclog (t) print (
        
        t.major.gender)
        print ( T.major.majorid)
        print (t.user.username)
7 The data from the previous step is the server-side data, but there are some minor episodes in the HTTP connection

(1) I used the cchttprequest in the Quick-cocos2d-x-lua package for server-side interaction, but not as much as the server-side data is PROTOBUF data. In the data that comes up after the debug trace, there's no end of it anywhere. This results in a study of the cchttprequest in Lua. Get string method data truncated cannot parse normally I am in Cchttprequest:: Getresponsestring processed data, and it's not going to work out.

(2) As a result of the project to use the short connection socket I have previously integrated luasocket, in fact, this open source socket is very easy to use with the support of HTTP decisively with this test server-side back data let me a little joy To parse it in the Protobuf.decode is exactly the data I want, but there's a bad place. Luasocket a timeout on the socket can be done without blocking the thread but HTPP the way I looked through the information on the website and I didn't find the non-blocking type. But this doesn't matter. Comparison can run protobuf the integration of a thread framework is OK ah, you can use a collaborative thread or LUA Llthreads Choose your own if you want to use Luasocket http first append luasocket http code

    Local HTTP = require ' socket.http ' local
    ltn12 = Require ' ltn12 ' response_body
    = ' "
    request_body =

    " "Func tion http.post (u) Local
        t = {} local
        R, c, h = http.request{
            url = u, 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
    end

    --url = "http ://www.baidu.com "
    r,c,h,body=http.post (http_url)
    print (c)
    if c~= then return
        end
    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])
    Cclog (t)

(3) But I did not use the above mentioned in the Luasocket HTTP personal feeling or directly with the coco2d-x in the cchttpclient more useful also do not have to deal with threads of things because I passed this test C + + The protobuf in the layer is completely fine, so I'm going to imitate the cchttprequest mentioned in (1) cocos2d:: extension:: Cchttpclient encapsulation use but a little bit of not smooth data to the LUA layer is still not normal, and I'm going to I'm glad I handled it. Processing the retrieved server data is as follows
std::vector<char> *data = Response->getresponsedata ();
    Std::stringstream MyStream;
        for (int i=0;i<data->size (); i++) {//if ((*data) [i]!= ' ") {MyStream << (*data) [i];
        }else{//MyStream << ' \b ';
    
    } Mresponsedata = Mystream.str ();
    Std::cout << mystream.str () << Std::endl;
    Cclog ("ddd:%s", Mystream.str (). C_STR ());
ccstring * CStr = ccstring::create (temp);
Com::sj::web::p roto::result *r = new Com::sj::web::p Roto::result::result ();
R->parsefromstring (Temp.c_str ());
    Cclog ("parsefromstring:::::::::%d%s", R->resultcode (), R->release_major ()->majorcode (). C_STR ());
    Ccluavaluedict dict;
    dict["Request"] = Ccluavalue::ccobjectvalue (This, "HttpRequest"); dict["data"] = Ccluavalue::stringvalue (Mystream.str ());
    Returns the value to the LUA layer dict["datacstring"] = Ccluavalue::ccobjectvalue (CStr, "ccstring"); dict["dddd"] = Ccluavalue::stringvalue ("dsSddsdsds ");
    Lua_function listener = (lua_function) response->gethttprequest ()->getuserdata ();
    Ccluastack *stack = ccluaengine::d efaultengine ()->getluastack ();
    Stack->clean ();
 Stack->pushccluavaluedict (DICT);

Do the previous step to modify the Cocos2d-x CCLuaStack.cpp method Pushccluavalue (...) code 293 lines of code, modify the following (this can be used directly lua_pushlstring (M_state, StringValue, length) press all data to the LUA upper level

Return pushstring (Value.stringvalue (). C_STR (), Value.stringvalue (). Length ());

The Complete method code is:
void Ccluastack::p ushccluavalue (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 ());
    }

All right, here we go. Hopefully, it will help cocos2d-x LUA developers if there is any good protobuf support for cocos2d-x LUA or more convenient integration please give me a piece of yo thank you

I use the situation of PBC experience generally can be

1 floating-point type: Java->lua no problem; Lua->java failed. The Java estimate for our backend is that Lua's decode of number floating-point types is not converted to floating-point types (or because of the high status conversion failure of Java when the type is more tightly led to decoding) Since the development efficiency is changed to string for delivery (tested Protoc-gen-lua also has this problem) if a friend can use Lua->java to do floating-point type communication OK desperately want you to share my solution

2 enumeration type proto file ordinal number starting from 1 otherwise the PBC PB file failed to load

3 The above mentioned loading PB file, iOS win can also be based on ccfileutils to obtain PB file path after the use of LUA IO Register, test android (I still read the method mentioned above) in this way did not succeed It should be the path and permissions problem (which has been verified to read the file path problem in Android, my way is to write Proto to the local post Lua read OK with IO) and not read the file

--Other platforms 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 follows local
FilePath = Calljava () local
        addr = Io.open (FilePath, "RB")
        Protobuffer = Addr:read "*a"
        addr:close ()
        protobuf.register (Protobuffer)

Recently, Google products and services to the full ban on the domestic Internet control of the expression of spit but good technical results are unbounded (I protobuf use, as always, if you want to use, please agent to download it) on the use of PROTOBUF summary

1) found that the byte on the data transmission is particularly light, from this advantage transmission speed is significantly faster than other such as JSON, especially for game communication, if it is to take into account the user traffic and bandwidth resource savings issues can be considered

2 A bad thing is that the client output data is not full estimate is the PBC deserialization Optimization Table object problem (and back-end interactive data is Java-written small client log output view, just to facilitate viewing back-end return data) and then back to the LUA project processing information


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.