调试protobuffer接口的神器——luapb

  

 luapb和云风写的lua-pbc(git://github.com/cloudwu/pbc.git)并不是一个东西。它们最主要的区别是:pbc虽然也不需要把.proto文件生成.js文件后使用,但是它却需要生成.pb文件;luapb是完全不需要生成任何中间文件,可以直接对.proto文件操作。

   luapb是开源的一个小项目,源码也很小。github的连接为: https://github.com/zhanjunxiong/luapb

       我在工作中经常遇到要和后端的protobuffer对象调试,后端的程序是C封装的protobuffer,前端是用protojs(https://github.com/sirikata/protojs)解析protobuffer对象;在调试的过程中为了能更好的验证接口,luapb可以快速的验证;还是直接看代码吧:

利用luapb动态的填充protobuffer对象的文件simple.lua:

///////////////

require("luapb")

function encodeSimp()
    pb.import("simple.proto")
    local msg = pb.new("simple.Simple")
    msg.name = "jack"

    msg.id = 2

扫描二维码关注公众号,回复: 3080091 查看本文章

    msg.email = "[email protected]"

    msg.longid = 18446744073709551615

    --[[ for decode

    local resProto = pb.new("simple.Simple")

    pb.parseFromString(resProto, decStr)
    print("res:",resProto.uid)

   ]]--

    return pb.serializeToString(msg)
end

proto文件:simple.proto

package simple;

message Simple {
  required string name = 1;
  required int32 id = 2;  
  optional string email = 3;
  required uint64 longid = 4;
}

从上面的例子中可以看到,luapb的用法比较直观;适合需要快速开发的场景。似乎太简单了也不需要多的解释。

和server端通信的文件send.lua, 通信的方式是zmq,假设在本地的8765端口起了一个server程序:

require("zmq")

function writeFile(file,str)
        local f = assert(io.open(file, "w"))
        f:write(str)
        f:close()
end

function readIO()
        local method = os.getenv("REQUEST_METHOD")     
        local cmd = ""
        if method == "POST" then
                local len = os.getenv("CONTENT_LENGTH")                        
                cmd = io.read(tonumber(len))           
        elseif method == "GET" then
                cmd = os.getenv("QUERY_STRING")
        end  
          
        local addr = os.getenv("REMOTE_ADDR") 
        local uci = luci.model.uci.cursor()
        uci:tset("luci","sysauth_info",{ipaddr=addr}) 
            uci:save("luci")
            uci:commit("luci")          
            
        return cmd
end

function send_one(reqstring)
        local cmd = reqstring
        if cmd ~="" then    
                local ctx = zmq.init(1,1,0)
                local s = ctx:socket(zmq.REQ)  
    
                local path = "tcp://127.0.0.1:8765"
    
                s:connect(path)
                s:send(cmd)   
                local result=s:recv()  
          writefile(result)
    
                io.write(result)    
                s:close()
                ctx:term()
        else
                io.write("")
        end 
end

dofile("simple.lua")
local req = encodeSimp()
local resString = send_one(req)
print("Decode Message:"..resString)

以上的这部分代码实现的是lua-zmq的通讯,即利用lua-zmq将动态填充的proto对象发送到server端;反之我们也通过lua-zmq接受server端返回的proto,并用luapb解析。

luapb提供的API有:

new:新建一个pb的对象;                                         用法:  pb.import("simple.proto"); local msg = pb.new("simple.Simple")

import:导入proto文件;                                         用法: pb.import("simple.proto")

tostring: 转化成stringpb.serializeToString(msg)

parseFromString:解析成proto对象,用于decode时;  用法:local resProto = pb.new("lm.test"); pb.parseFromString(resProto, decStr); print("res:",resProto.uid)

serializeToString:序列化proto, 用于encode时;       用法:pb.serializeToString(msg)

https://www.cnblogs.com/mashiaoo/p/3523087.html

猜你喜欢

转载自blog.csdn.net/larry_zeng1/article/details/81627518
今日推荐