Unity手游之路<二>Java版服务端使用protostuff简化protobuf开发
2014-06-25 17:27
483 查看
开发一款网络游戏,首先要考虑的是客户端服务端之间用何种编码格式进行通信。之前我们介绍了Unity游戏前端使用protobuf的方法。今天我们来谈谈服务端如何使protobuf。游戏服务端语言百花齐放,除了比较传统的c/c++外,Java,Erlang,Python都有很多团队在使用。
今天推荐一下Java作为服务端开发语言。国内很多出色的页游和手游都是采用Java作为服务端语言的。比如《神曲》《秦美人》《龙将》《时空猎人》
等,不一而足。
本文主要探讨如何简化Protobuf程序的开发。
传统方式
按照传统的开发流程,都是如下:
1.先编写proto文件格式,例如
[plain]
view plaincopyprint?
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类的相关函数进行序列化和反序列化
[java]
view plaincopyprint?
//序列化
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,正是基于这种思路的。
改进版
1.编写Person类(为了使demo代码精简,字段都暂时设为public)
[java]
view plaincopyprint?
public class Person{
public int id;
public String name;
public String email;
}
2.测试序列化和反序列化
[java]
view plaincopyprint?
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 = "ken@iamcoding.com";
// 缓存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的这种反射,会不会比官方推荐的反射性能差很远呢?没有调查,就没有发言权。有人已经测试了,性能方面还是差不多的,可以放心使用。
具体的测试数据可以去查阅网上相关的数据,在此省略了。
总结
Protostuff的优势是将开发流程简化,让我们可以更高效,更专注地开发。有任何问题欢迎一起探讨ken@iamcoding.com
下一篇,我将会用一个完整的demo,将整个Unity客户端和服务端的通信流程串联起来。
今天推荐一下Java作为服务端开发语言。国内很多出色的页游和手游都是采用Java作为服务端语言的。比如《神曲》《秦美人》《龙将》《时空猎人》
等,不一而足。
本文主要探讨如何简化Protobuf程序的开发。
传统方式
按照传统的开发流程,都是如下:
1.先编写proto文件格式,例如
[plain]
view plaincopyprint?
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类的相关函数进行序列化和反序列化
[java]
view plaincopyprint?
//序列化
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,正是基于这种思路的。
改进版
1.编写Person类(为了使demo代码精简,字段都暂时设为public)
[java]
view plaincopyprint?
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.测试序列化和反序列化
[java]
view plaincopyprint?
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 = "ken@iamcoding.com";
// 缓存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 = "ken@iamcoding.com"; // 缓存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的这种反射,会不会比官方推荐的反射性能差很远呢?没有调查,就没有发言权。有人已经测试了,性能方面还是差不多的,可以放心使用。
具体的测试数据可以去查阅网上相关的数据,在此省略了。
总结
Protostuff的优势是将开发流程简化,让我们可以更高效,更专注地开发。有任何问题欢迎一起探讨ken@iamcoding.com
下一篇,我将会用一个完整的demo,将整个Unity客户端和服务端的通信流程串联起来。
相关文章推荐
- [原]Unity手游之路<二>Java版服务端使用protostuff简化protobuf开发
- Unity手游之路<二>Java版服务端使用protostuff简化protobuf开发
- [原]Unity手游之路<二>Java版服务端使用protostuff简化protobuf开发
- Unity手游之路<二>Java版服务端使用protostuff简化protobuf开发
- JAVA处理时间<二>
- 安装sybase出现 找不到JVM错误请使用选项 -is:javahome<JAVA HOME DIR>
- 程序员_Java初级<二> 关键字、标识符、运算符、进制
- <转>学习java反编译工具的使用
- oracle的使用<二>查询
- <<Think in Java 4 >>中关于使用XOM操作xml文件
- Maatkit工具使用<二>之mysql重复索引检测工具
- 使用java 正则表达式 只替换排除< >之内的内容
- 30分钟学会使用Ajax:<二>
- 安装sybase出现 找不到JVM错误请使用选项 -is:javahome<JAVA HOME DIR>
- 黑马程序员 JAVA基础<二> 面向对象之封装 继承 多态
- java中使用<jsp:forward>报404错误
- Java中使用hql,sql查询返回的list<Object> 转成需要的实体对象--方法讲解!
- Lesson2 使用Hello ACCP.NET快速热身<二>
- jsp使用javabean<jsp:useBean>
- 使用 jQuery 简化 Ajax 开发<转>