今天推薦一下Java作爲服務端開發語言。國內很多出色的頁遊和手遊都是採用Java作爲服務端語言的。比如《神曲》《秦美人》《龍將》《時空獵人》
等,不一而足。
本文主要探討如何簡化Protobuf程序的開發。
- 傳統方式
按照傳統的開發流程,都是如下:
1.先編寫proto文件格式,例如
- message Person {
- required int32 id = 1;
- required string name = 2;
- optional string email = 3;
- }
message Person {
required int32 id = 1;
required string name = 2;
optional string email = 3;
}
2.運行編譯程序,生成實體類Person.java
protoc --java_out=./src ./person.proto
3.在程序中可以直接使用Person類的相關函數進行序列化和反序列化
- //序列化
- Person person = builder.build();
- byte[] buf = person.toByteArray();
- //反序列化
- Person person2 = PersonProbuf.Person.parseFrom(buf);
//序列化
Person person = builder.build();
byte[] buf = person.toByteArray();
//反序列化
Person person2 = PersonProbuf.Person.parseFrom(buf);
上面的流程看似很方便了,有什麼問題呢?還能不能再改進呢?我們先看看生成的Person類代碼吧,竟然有幾千行。實際上我們只是包含了3個變量而已,可讀性大大降低了。其次,開發過程每次都得藉助外部的編譯工具來生成代碼。
於是我們可能就有了一個簡單的思路。自己編寫Person的類,然後通過外部的api,直接對這個類進行序列化和反序列化。
直接拋棄了protoc工具。
這個思路,已經有人實現出來了,最早是在c#語言版本的protobuf-net實現了。它利用c#的Attribute(類似Java的Annotation註解)+反射來實現普通實體類的Protobuf序列化和
反序列化。
本想自己把protobuf-net的c#代碼轉換成Java代碼。後來在OverStack中翻到有人介紹Protostuff,正是基於這種思路的。
- 改進版
- public class Person{
- public int id;
- public String name;
- public String email;
- }
public class Person{
public int id;
public String name;
public String email;
}
2.測試序列化和反序列化
- public static void main(String[] args) throws IOException {
- // //類的模式設置爲Person類
- Schema<Person> schema = RuntimeSchema.getSchema(Person.class);
- Person person1 = new Person();
- person1.id = 10086;
- person1.name = "ken";
- person1.email = "[email protected]";
- // 緩存buff
- LinkedBuffer buffer = LinkedBuffer.allocate(1024);
- // 序列化成protobuf的二進制數據
- byte[] data = ProtobufIOUtil.toByteArray(person1, schema, buffer);
- // 反序列化
- Person person2 = new Person();
- ProtobufIOUtil.mergeFrom(data, person2, schema);
- System.out.println(person2.id);
- }
public static void main(String[] args) throws IOException {
// //類的模式設置爲Person類
Schema<Person> schema = RuntimeSchema.getSchema(Person.class);
Person person1 = new Person();
person1.id = 10086;
person1.name = "ken";
person1.email = "[email protected]";
// 緩存buff
LinkedBuffer buffer = LinkedBuffer.allocate(1024);
// 序列化成protobuf的二進制數據
byte[] data = ProtobufIOUtil.toByteArray(person1, schema, buffer);
// 反序列化
Person person2 = new Person();
ProtobufIOUtil.mergeFrom(data, person2, schema);
System.out.println(person2.id);
}
更多的功能可以去詳細閱讀相關的手冊吧。比如,指定實體類字段的序列化順序,忽略某些字段不被序列化等等。
- 性能考慮
具體的測試數據可以去查閱網上相關的數據,在此省略了。
- 總結
Protostuff的優勢是將開發流程簡化,讓我們可以更高效,更專注地開發。有任何問題歡迎一起探討[email protected]
下一篇,我將會用一個完整的demo,將整個Unity客戶端和服務端的通信流程串聯起來。