調試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
    msg.email =  "jack@request.com"
    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)
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM