Unity3D客户端和Java服务端使用Protobuf
轉自:http://blog.csdn.net/kakashi8841/article/details/17334493
前幾天有位網友問我關于Unity3D里面使用Protobuf的方法,一時有事拖到現在才寫這篇文章,不好意思哈。
本文測試環境:
系統:WINDOWS 7(第3、6步)、OS X 10.9(第4步)
軟件:VS 2012(第3、6步)、Eclipse(第5、6步)
硬件:iPad 2(第4步)、Macbook Pro Mid 2012(第4步)
?
文章目錄:
1、關于Protobuf的C#實現
2、為什么有些Protobuf發布到iOS就用不了,甚至有些在PC都用不了?
3、手動處理C#版本的Protobuf
?
? ? 3.1、創建一個C#工程,先手動創建每一個要通過Protobuf序列化或反序列化的數據模型類,然后導出dll
? ? 3.2、創建一個用于序列化的C#工程,然后運行生成dll
? ? 3.3、將上面兩個工程生成的dll拖到unity中
4、在Unity中反序列化Protobuf
5、服務端Java也用Protobuf
6、太煩了?!客戶端也要自動處理Protobuf
?
1、關于Protobuf的C#實現
首先,U3D里面Protobuf使用的是C#的實現,那么目前有幾個可選的C#實現:
C#: http://code.google.com/p/protobuf-csharp-port
C#: http://code.google.com/p/protosharp/
C#: https://silentorbit.com/protobuf/
C#/.NET/WCF/VB: http://code.google.com/p/protobuf-net/
?
我這里選用的是http://code.google.com/p/protobuf-net/(你可以在https://code.google.com/p/protobuf-net/downloads/list?這里下載到他的代碼和工具),它比較好的一點是,提供了各種平臺的支持,解壓后在“Full”目錄中可以看到各個平臺的支持。(現在google被各種封殺,如果你打不開上面的地址,可以下載我上傳到CSDN的,里面的csharp文件夾就是各個平臺的protobuf需要的dll,點擊下載protobuf-net)。
看到里面的unity了嗎,它里面的protobuf-net.dll將是我們準備用到的。
?
2、為什么有些Protobuf發布到iOS就用不了,甚至有些在PC都用不了?
a、Protobuf使用了JIT,即在運行時動態編譯,而這個特性在Unity發布到iOS時候是不支持的。因此,會導致你在PC上可以正常運行,發布到iOS就有問題。
b、Protobuf是基于.net 2.0以上框架寫的,而Unity僅支持.net 2.0,或者有些使用2.0中比較多的特性,而你在Unity中發布設置了.net 2.0的子集。后者你只需要在Player setting中修改設置就可以了。
上面兩項也可適用于其它第三方類庫,如果你自己下載了一個在PC上或C#里面能正常使用的類庫,在U3D里面就不能用了,那么請檢查是否是上面兩條原因導致的。
?
3、手動處理C#版本的Protobuf
知道了上面問題,我們只要選一個.net2.0的Protobuf,然后它又不是JIT,那就可以正常使用了。
這里用的思路是:
? ? 3.1、創建一個C#工程,先手動創建每一個要通過Protobuf序列化或反序列化的數據模型類,然后導出dll
? ? ? ? 以VS為例,首先,創建一個類庫工程:“文件”>"新建">"項目">"類庫"(記得選擇 .net framework 2.0)
將unity的protobuf的dll添加到項目引用
然后假設你有一個類WorkerInfo是需要通過Protobuf進行序列化和反序列化的,那么創建一個WorkerInfo類,內容如下:
?
[csharp]?view plaincopy按下Shift+F6生成dll,在項目的bin\Debug目錄下就可以找到ProtoModelDLL.dll了
?
?
? ? 3.2、創建一個用于序列化的C#工程,然后運行生成dll
? ? ? ? 也是以VS為例,首先創建一個控制臺應用程序:“文件”>"新建">"項目">"控制臺應用程序"(記得選擇 .net framework 2.0)
將Protobuf和3.1生成的dll添加到引用
在項目生成的Program.cs中寫入:
?
[csharp]?view plaincopy
然后ctrl+F5運行,這時候你就可以在bin\Debug中看到ProtoModelSerializer.dll。
?
? ? 3.3、將上面兩個工程生成的dll(ProtoModelDLL.dll和ProtoModelSerializer.dll)以及protobuf-net.dll拖到unity中
? ? ? ??怎么用?看第4步
4、在Unity中反序列化Protobuf
由于一般游戲客戶端請求的數據量比較簡單,也比較少,因此我們前端請求是不直接二進制請求。而前端收到后端返回才采用了Protobuf,因此。這里只討論Protobuf的反序列化。
代碼很簡單,下面寫個測試代碼:
?
[csharp]?view plaincopy
?
運行后Unity控制臺輸出了worker的信息。代碼中的dataFromServ字節數組的內容實際應該是通信時候后端返回的。這里測試就不涉及Socket通信的知識了。
5、服務端Java也用Protobuf
看到一個客戶端用Protobuf這么麻煩,那后端會怎樣呢?其實后端是比較簡單的,有Google官方的支持。
下載:https://code.google.com/p/protobuf/downloads/list
下完解壓是這樣的(2.5.0):
進入“protobuf-2.5.0\java”文件夾,里面是一個maven項目,你直接用maven clean install在target目錄就會生成一個protobuf-java-2.5.0.jar的jar包了,沒maven的在這里下載吧,我用maven生成的http://download.csdn.net/detail/kakashi8841/6723689。這個要時候導入你的Java項目。就可以了。
然后你寫一個proto文件,調用“protobuf-2.5.0\src”里面的protoc.exe進行生成,它會幫你生成一個java文件。(詳細看https://developers.google.com/protocol-buffers/docs/javatutorial),我這里有提供一個bat,用于調用protoc來生成java文件的,手動輸入的話太麻煩了。在windows下把它保存到.bat然后雙擊運行就可以了。
?
[vb]?view plaincopy
OK啦,這樣你只要把生成的Java復制到或直接生成到你的Java項目源碼目錄中,然后就可以使用了。比如:
以前面說的WorkerInfo為例
?
?
[java]?view plaincopy
控制臺就會輸出:
?
細心的同學會發現這里的字節和上面的“8, 233, 7, 16, 100, 24, 1”有點不太一樣。第二個數字分別為-23和233.
其實,這個只是byte的有無符號的表示差異而已。
他們的二進制表示都是:11101001
?
6、太煩了?!客戶端也要自動處理Protobuf
我們看到客戶端沒加一個類,都需要在兩個VS項目中增加代碼,而后端是直接根據proto文件生成代碼的。這樣,好像有點不公平,而且這樣前后端還是可能會寫出不一樣的結構。其實用protobuf我個人覺得最大的好處:
? ? a、數據量小
? ? b、通過proto模板生成代碼,減少前后端聯調
但是現在只是后端減少了工作,前端并沒有減少,因此第二個好處不是很明顯。
那好吧。我沒有就這樣滿足。因此,我決定,前端也要根據proto來生成cs文件。
因此,我使用Java編寫了一個解析Proto文件的工具,并且根據proto生成cs文件,然后用bat調用vs的命令行執行vs項目的構建,最后生成兩個dll。
我把上面的命令都整合到一個bat中,因此這個bat的任務是:
執行java程序,把proto文件生成cs文件。
調用vs接口構建兩個vs項目,生成兩個dll。
通過svn把這兩個dll提交到客戶端的主干上。
調用上面根據proto生成java的bat片段,生成java代碼。
通過svn把生成的java代碼提交到服務端主干上。
因此,這樣一來,現在只要編寫好proto文件,然后雙擊bat,前后端就都可以通過更新svn來獲取最新的Protobuf數據對象。
?
bat運行
根據proto生成cs文件并編譯執行兩個vs項目,然后把生成的dll提交到svn上
生成java代碼并提交svn
這一步相關操作大家有興趣可以自行試試,有問題歡迎在本博客討論。
總結
以上是生活随笔為你收集整理的Unity3D客户端和Java服务端使用Protobuf的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对一个程序单元测试
- 下一篇: iTween 动画类型