• Unity手游之路<二>Java版服务端使用protostuff简化protobuf开发


    http://blog.csdn.net/janeky/article/details/17151465

    开发一款网络游戏,首先要考虑的是客户端服务端之间用何种编码格式进行通信。之前我们介绍了Unity游戏前端使用protobuf的方法。今天我们来谈谈服务端如何使protobuf。游戏服务端语言百花齐放,除了比较传统的c/c++外,Java,Erlang,Python都有很多团队在使用。

    今天推荐一下Java作为服务端开发语言。国内很多出色的页游和手游都是采用Java作为服务端语言的。比如《神曲》《秦美人》《龙将》《时空猎人》

    等,不一而足。

    本文主要探讨如何简化Protobuf程序的开发。

    • 传统方式

    按照传统的开发流程,都是如下:

    1.先编写proto文件格式,例如

    [plain] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. message Person {  
    2.   required int32 id = 1;  
    3.   required string name = 2;  
    4.   optional string email = 3;  
    5. }  


    2.运行编译程序,生成实体类Person.java
    protoc  --java_out=./src   ./person.proto


    3.在程序中可以直接使用Person类的相关函数进行序列化和反序列化

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. //序列化  
    2. Person person = builder.build();  
    3. byte[] buf = person.toByteArray();  
    4. //反序列化  
    5. 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 plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public class Person{  
    2.     public int id;  
    3.     public String name;  
    4.     public String email;  
    5. }  


    2.测试序列化和反序列化

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public static void main(String[] args) throws IOException {  
    2.         // //类的模式设置为Person类  
    3.         Schema<Person> schema = RuntimeSchema.getSchema(Person.class);  
    4.         Person person1 = new Person();  
    5.         person1.id = 10086;  
    6.         person1.name = "ken";  
    7.         person1.email = "ken@iamcoding.com";  
    8.         // 缓存buff  
    9.         LinkedBuffer buffer = LinkedBuffer.allocate(1024);  
    10.         // 序列化成protobuf的二进制数据  
    11.         byte[] data = ProtobufIOUtil.toByteArray(person1, schema, buffer);  
    12.   
    13.   
    14.         // 反序列化  
    15.         Person person2 = new Person();  
    16.         ProtobufIOUtil.mergeFrom(data, person2, schema);  
    17.         System.out.println(person2.id);  
    18.     }  


    更多的功能可以去详细阅读相关的手册吧。比如,指定实体类字段的序列化顺序,忽略某些字段不被序列化等等。

    • 性能考虑

    一开始,考虑到Protostuff的这种反射,会不会比官方推荐的反射性能差很远呢?没有调查,就没有发言权。有人已经测试了,性能方面还是差不多的,可以放心使用。
    具体的测试数据可以去查阅网上相关的数据,在此省略了。

    • 总结

    Protostuff的优势是将开发流程简化,让我们可以更高效,更专注地开发。有任何问题欢迎一起探讨ken@iamcoding.com

    下一篇,我将会用一个完整的demo,将整个Unity客户端和服务端的通信流程串联起来。

  • 相关阅读:
    [Leetcode] Swap Nodes in Pairs
    [Leetcode] Roman to Integer
    [Leetcode] Search Insert Position
    [Leetcode] String to Integer (atoi)
    [Leetcode] Count and Say
    [Leetcode] Valid Palindrome
    [Leetcode] Implement strStr()
    一起手写吧!防抖和节流
    CSS系列,清除浮动方法总结
    css系列,选择器权重计算方式
  • 原文地址:https://www.cnblogs.com/123ing/p/4114858.html
Copyright © 2020-2023  润新知