gogoprotobuf在windows上遇見的坑

閒話一下

  1. 最近打算做一個聯網的小遊戲,通訊協議決定使用protobuf,之前的工作環境都是在linx下進行開發的,這次我打算從零開始,在windows系統下開發,而這篇文件也主要介紹我如何配置gogoprotobuf的環境,以及期間遇到的問題。不是protobuf麼,爲何變爲gogoprotobuf?因爲網上查了下資料,發現gogoprotobuf生成速度比protobuf還要快一些,既然如此爲何不用更好的。

準備工作

首先你需要在github上下載github.com/gogo/protobuf和github.com/Knetic/govaluate,沒翻牆?下載速度1kb/s?我已經給你們準備好了,之前我下了3個小時,放在我的網盤地址上了(掛了請留言)。
然後你需要一個編譯好了的protoc的可執行文件,你可以在github.com/protocolbuffers/protobuf下載源碼,然後在本機上編譯。也可以直接從官網下載已經生成好了的可執行文件,地址如下github.com/google/protobuf/releases。我這邊生成發現少了好多依賴包,節約時間,就自己下了個windows的64位的文件。也放在網盤上的。

網盤地址:https://pan.baidu.com/s/1lnv5F3IFcTcGQBa1nqgijQ
提取碼:hi4d

創建你的工程目錄

你下載的github.com文件夾拷貝到src目錄下,並在src目錄下創建一個test文件夾,我的test是我的項目名字,等會我會把proto文件放在這個目錄下。

工程目錄創建項目

接下來你要編譯gogo的protoc-gen-go文件,進入github.com\gogo\protobuf\protoc-gen-gogofast和github.com\gogo\protobuf\protoc-gen-gogo(這裏我就選用了這2個),使用go
build命令生成可執行文件。並將生成的文件和protoc.exe一起放入bin目錄下。


放在bin目錄下
接下來在我們的test文件夾裏創建一個proto文件,並附上內容
創建proto文件

syntax = "proto3";
package gameMsg;

import "github.com/gogo/protobuf/gogoproto/gogo.proto";

//option (gogoproto.goproto_sizecache_all) = false;
//option (gogoproto.goproto_unkeyed_all) = false;
//option (gogoproto.goproto_unrecognized_all) = false;


enum TestPid {
    cInvalid = 0; //無效的消息id
	cLogin = 1000; //登陸請求
    cLogout = 1001; //登出請求
}

//協議頭
message PbTest {
	option (gogoproto.goproto_getters) = false;
    string PlayerId = 1; 			//用戶id
    string Sign = 2; 				//簽名
    int32 Tick = 3; 				//時間戳()
}

生成go文件

如果你對生成的go的格式沒有什麼要求,把上面的引用gogo.proto註釋掉,執行下面的命令就應該行了。而作爲有強迫症的我,就只有默默的踩坑。

 %GOPATH%\bin\protoc.exe --plugin=protoc-gen-go=%GOPATH%\bin\protoc-gen-gogo.exe  --go_out=. base.proto(%GOPATH%你們這個需要自己在環境變量裏面改,我這裏的是E\gotest,protoc-gen-gogo.exe就是剛纔我們生成的文件)

然後報錯,具體就是說缺少google/protobuf/descriptor.proto文件,我在目錄下一看,確實沒這個包,咋辦呢?我突然想到了之前gogoproto介紹說兼容了google的proto,那麼肯定本地應該有這個文件的,果然不出我的猜想,在github.com\gogo\protobuf\protobuf目錄下發現了google文件夾,然後順騰摸瓜就找到了descriptor.proto文件。

在這裏插入圖片描述

在這裏插入圖片描述

於是我們就改下這個gogo.proto中descriptor.proto的地址吧,在改之前最好拷貝一份,做個備份,萬一你的git回滾不了呢

在這裏插入圖片描述
github.com/gogo/protobuf/protobuf/google/protobuf/descriptor.proto

這次我們再試一試,生成go文件成功,這下我們就可以使用這個gameMsg了

在這裏插入圖片描述
在這裏插入圖片描述

我們還想要更簡潔的代碼

上面的代碼被我標註紅色的可以看出,這些東西看着是不是很彆扭,因爲對我而言,我根本用不着這些,我解析都有自己的一套規則,還有加密算法在裏面,所以我只需要生成這個結構體部分就行了,多餘的部分那就想辦法幹掉它。

於是通過網上查詢,找到了一些取消這個字段的方法,具體不多講,百度能查到各個字段的意思,有興趣的朋友可以查查。 option
(gogoproto.goproto_sizecache_all) = false; option
(gogoproto.goproto_unkeyed_all) = false; option
(gogoproto.goproto_unrecognized_all) = false;

然後我們看到的效果是果然xxx的字段沒有了,但是下面的函數帶xxx的還有。

在這裏插入圖片描述

我有時候都懷疑我是金牛座的——犟,查了大量網上資料無果後,咋辦?看源碼吧,找到它,接近它,幹掉它(就是這麼暴力)。

最後在github.com/gogo/protobuf/protoc-gen-gogo/generator裏找到了XXX_Unmarshal,它是在generateCommonMethods函數裏,大致看了一下,這裏就是它自動給你生成函數的地方,查看調用的地方,註釋了沒啥影響,註釋掉。

從生成protoc-gen-gogo.exe的main開始找,發現調用的command文件
從command文件裏,發現調用了generator文件
搜索XXX_Unmarshal,找到了這個地方
這就是那個自動生成函數的代碼
註釋掉

然後重新編譯下protoc-gen-gogo.exe吧,編譯好了記得替換掉bin目錄下的protoc-gen-gogo.exe
然後執行,看看結果,果然不見了,現在是不是看着清爽多了,當然你如果還是想用工具裏自帶的序列化和反序列化,那你還是保留吧。

在這裏插入圖片描述

總結

工具這東西就是爲了讓我們使用方便的東西,如果當使用費勁的時候,我們就應該想如何去解決問題,把複雜的東西簡單化,提高效率纔是我們所不斷追求的目標。希望這篇文章能帶給那些需要人一些幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章