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());
                        }
                    });

 

 

 

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