天天看點

Protobuf與lua服務端

protocolbuffer(以下簡稱PB)是google 的一種資料交換的格式,它獨立于語言,獨立于平台。google 提供了多種語言的實作:java、c#、c++、go 和 python,每一種實作都包含了相應語言的編譯器以及庫檔案。由于它是一種二進制的格式,比使用 xml 進行資料交換快許多。可以把它用于分布式應用之間的資料通信或者異構環境下的資料交換。作為一種效率和相容性都很優秀的二進制資料傳輸格式,可以用于諸如網絡傳輸、配置檔案、資料存儲等諸多領域。

  之前一直不知道protobuf還有類似數組的這種資料類型,在遊戲服務端和用戶端互動時總是人為的去構造一直資料類型來解析傳遞到用戶端的連結清單資料。總覺得很不友善,今天再次看了下官方文檔,發現repeated字段便能實作類似數組的功能,這令我大為欣喜。主要之前為了求快,不斷滿足公司demo的功能,沒有仔細看協定變依葫蘆畫瓢開始開發了,果然這樣子有點費力不讨好。

  由于遊戲的服務端采用的是Lua來寫邏輯,這裡就記錄下如何用lua來構造資料并編碼的。

syntax = "proto2";
package test;
import "empty_msg.proto";
// 功能測試
service Test {
    rpc TestArray(rpc.EmptyMsg) returns (ArrayTestData);
}
message TestModel
{
    optional int32 id = 1;
    optional int32 value = 2;
}
message ArrayTestData{
    repeated TestModel testModel = 1;
}
           

對應的Lua腳本

local resTable = {}
local resp = {id = ,value = }
local resp1 = {id = ,value = }
table.insert(resTable,resp)
table.insert(resTable,resp1)
local arrayTestData = {testModel = resTable}
c_rpc.reply_to(ctx, pb.encode("test.ArrayTestData", arrayTestData))
           

  其實是很簡單的東西,但是由于一個小問題,導緻我花了一下午才搗鼓出來,是以就貼出來,防止自己下次再犯錯。之前在lua腳本裡面我是這麼寫的

local arrayTestData = {resTable}

,因為參見上面protobuf的協定設計,直覺的認為test.ArrayTestData僅僅是一個存放test.TestModel資料類型的一個數組而已。其實邏輯就錯在了這裡,是test.ArrayTestData裡面的一個資料成員testModel這個對象才是存放數組的,所有必須要使用testModel = resTable,否則會編碼出錯。