Google protobuf 编码解码

官网

https://developers.google.com/protocol-buffers

Protocol buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data.

protobuf是一个跨语言,平台的,可以序列化结构性数据的可扩展解决方案。

也就是一个序列化框架。

支持的语言还挺多。

 

安装方式见官网,如果是Ubuntu系统,那就是一句命令的事情

sudo apt install protobuf-compiler
message xxx {
  // 字段规则:required -> 字段只能也必须出现 1 次
  // 字段规则:optional -> 字段可出现 0 次或1次
  // 字段规则:repeated -> 字段可出现任意多次(包括 0)
  // 类型:int32、int64、sint32、sint64、string、32-bit ....
  // 字段编号:0 ~ 536870911(除去 19000 到 19999 之间的数字)
  字段规则 类型 名称 = 字段编号;
}

编写proto文件, 定义数据结构

syntax= "proto2";
//永远不要修改生成的代码,只能修改这里的代码
package com.protobuf.test;

option optimize_for = SPEED;//加快解析速度,详细可以去官网查
option java_package="com.huang.protobuf.test";
option java_outer_classname="PersonEntity";
message MyMessage{
    //定义一个枚举类型DataType
    enum DataType{
        PersonType=1;
        DogType=2;
        CatType=3;
    }
    //用data_type来标识传的是哪个枚举类型
    required DataType data_type=1;
    //表示每次枚举类型最多只能出现三个中的一个,节省了空间
    oneof dataBody{
        Person person=2;
        Dog dog=3;
        Cat cat=4;
    }

}
message Person{
    optional string name=1;
    optional int32 id=2;
    optional string address=3;
}
message Dog{
    optional string name=1;
    optional int32 age=2;
}
message Cat{
    optional string name=1;
    optional int32 age=2;
}

 

  编译protobuf文件

protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/Person.proto

 

在服务器端配置好ProtobufDecoder和ProtobufVarint32FrameDecoder解码器即可。

ProtobufDecoder负责解码protobuf二进制消息

ProtobufVarint32FrameDecoder 负责读取半包

bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 100)
                    .handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) {
                            // 试试看:注释掉下面这句(半包问题,程序会出错)
                            ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
                            ch.pipeline()
                                    .addLast(new ProtobufDecoder(SubscribeReqProto.SubscribeReq.getDefaultInstance()));
                            ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
                            ch.pipeline().addLast(new ProtobufEncoder());
                            ch.pipeline().addLast(new SubReqServerHandler());
                        }
                    });

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章