zoukankan      html  css  js  c++  java
  • Protocol Buffer使用转换工具将proto文件转换成Java文件流程及使用

    Client与Server的网络通信协议传输使用google protobuf,服务器端使用的是Java

    一、 Protocol Buffers
    protobuf全称Google Protocol Buffers,是google开发的的一套用于数据存储,网络通信时用于协议编解码的工具库。它和XML或者JSON差不多,也就是把某种数据结构的信息,以某种格式(XML,JSON)保存起来,protobuf与XML和JSON不同在于,protobuf是基于二进制的。主要用于数据存储、传输协议格式等场合。那既然有了XML等工具,为什么还要开发protobuf呢?主要是因为性能,包括时间开销和空间开销:

    1.时间开销:XML格式化(序列化)和XML解析(反序列化)的时间开销是很大的,在很多时间性能上要求很高的场合,你能做的就是看着XML干瞪眼了。

    2.空间开销:熟悉XML语法的同学应该知道,XML格式为了有较好的可读性,引入了一些冗余的文本信息。所以空间开销也不是太好(应该说是很差,通常需要实际内容好几倍的空间)。

    二、服务器端生成的proto文件转换成Java文件

    示例:proto文件

    syntax = "proto3";
    
    option java_package = "com.showly.app.chat.proto";//生成Java文件后的存放路径
    option java_outer_classname = "ChatServerProto";
    
    
    // 聊天内容类型
    enum ContentType {
        NORMAL = 0;         // 普通文本聊天
        ANONYMOUS = 1;         // 匿名文本聊天(输入框旁边有个勾选)
    }
    
    
    // 性别
    enum GenderType {
        SECRET = 0;             // 保密
        MALE = 1;                //
        FEMALE = 2;                //
    
    }
    
    
    // 用户信息
    message UserInfo {
        int32 uid = 1;
        string headPic = 2;
        GenderType gender = 3;
        bool vip = 4; //Vip
        int32 level = 5; //等级
        string nickName = 6; //昵称
    }
    
    
    
    // 响应消息的一个头. 每个消息都会带上.
    message ResponseHeader {
        int32  status = 1;            // 状态 非0 为失败
        string  msg = 2;             // 状态描述
    }
    
    
    // 聊天使用的消息体对象
    message ChatInfo {
        UserInfo info = 1;             // 用户信息
        string location = 2;             // 用户的位置. 
        ContentType type = 3;             // 消息类型
        bytes content = 4;             // 消息内容
        int64 dt = 5;                 // 时间戳
    }
    
    
    // cmdId = 1000(客户端传输到服务器端的请求id)
    message LoginRequest {
        int32 uid = 1;             //uid
        string token = 2;        // token
    }
    
    // cmdId = 1000000(客户端获取服务器端响应id)
    message LoginResponse {
        ResponseHeader header = 1;
        repeated ChatInfo chats = 2;            // 10条历史记录
        bool roomReconn = 3;                 // 房间重连
    }
    
    
    // cmdId = 1001 切换城市 世界为 "WORLD"
    message ChangeCityRequest {
        string  city = 1;                  // city code
    }
    
    
    // cmdId = 1000001
    message ChangeCityResponse {
        ResponseHeader header = 1;
        repeated ChatInfo chats = 2;// 10条历史记录
    }
    
    
    enum LocationType {
        WORLD = 0;//世界信息
        REDBAGROOM = 1; //红包活动房间
    }
    
    
    // cmdId = 1002
    message SendChatMsgRequest {
        string location = 1;        //位置
        ContentType type = 2;         // 消息类型
        bytes content = 3;             // 消息内容. 以后可能图片什么. 我这里不写死. 客户端给我字节数组.
        LocationType locationType = 4 ;// 消息位置
    }
    
    // cmdId = 1000002  推送的聊天信息广播协议
    message ChatInfoBroadcastResponse {
        ResponseHeader header = 1;     
        ChatInfo chat = 2;         // 广播的内容
        LocationType locationType = 3 ;// 消息位置
    } 
    
    // cmdId = 1003 心跳. 不需要发送东西. 告诉服务器还活着
    message HeartRequest {
    
    }
    
    // 这里仅服务端使用这个, 客户端按照下行的id 解析即可.
    message DefaultHeaderResponse {
        ResponseHeader header = 1;         //
    }

    转换流程:
    1、这时需要protoc转换工具(公众号回复"protocbuf转换工具")

    2、将proto文件放到工具相应的目录(如图)

    3、使用如图命令行进行转换

    转换后的Java文件为ChatServerProto(生成的文件代码太长,这里不放出来了)

    三、Protocol Buffer使用

    以使用Netty网络编程框架Protocol Buffer传输为例:

    Netty登录请求(此协议为客户端与服务端双方规定好的协议)
    // cmdId = 1000
    message LoginRequest {
        int32 uid = 1;             //uid
        string token = 2;        // token
    }

    项目代码中使用:

    ChatServerProto.LoginRequest loginRequest = ChatServerProto.LoginRequest
                    .newBuilder()
                    .setUid(Integer.parseInt(I8ShowSharePre.getHomeId(getActivity())))
                    .setToken(I8ShowSharePre.getToken(getActivity()))
                    .build();
    
            MessageContent messageContent = new MessageContent(1000, loginRequest.toByteArray());
            //nettyChatClient为netty对象
            nettyChatClient.sendMessage(messageContent);

    以下是个人公众号(longxuanzhigu),之后发布的文章会同步到该公众号,方便交流学习Android知识及分享个人爱好文章:

  • 相关阅读:
    关于HashMap初始化容量问题
    nohu和&
    (转)ShardedJedisPool的使用
    Mysql 索引问题-日期索引使用
    mysql 索引 大于等于 走不走索引 最左前缀
    tomcat开启https协议
    Hystrix的原理与使用
    Hystrix使用Commond的三种方式
    Redis 面试题(持续更新)
    如何进行用户访谈更容易获得全面而有效的信息
  • 原文地址:https://www.cnblogs.com/showly/p/11062705.html
Copyright © 2011-2022 走看看