title: protobuf集成netty实现多协议消息传递
date: 2019-05-21 19:37:28
categories:
- netty
tags: - protobuf集成netty
介绍
当使用socket
传输数据时,客户端服务端进行交互时,必须要知道数据类型,才能将数据序列化,在使用protobuf
进行序列化时,可以使用官方推荐的方式实现多数据类型的传输。
proto文件
message MyMessage{
enum DataType{
StudentType = 1;
DogType = 2;
TeacherType =3;
}
required DataType data_type = 1;
oneof dataBody{
Student student = 2;
Teacher teacher = 3;
Dog dog = 4;
}
}
message Student {
required string name = 1;
optional int32 id = 2;
optional string email = 3;
}
message Dog {
required string name = 1;
optional string type = 2;
}
message Teacher {
required string name = 1;
optional string address = 2;
}
在.proto
文件中定义一个“外部”的类来进行包装所想要传递的一些数据类型,用枚举类型来表示包装在其中的数据类型是什么,data_type
就来指明数据类型,dataBody
就是所要传输的数据。
oneof
官方解释:如果有一个包含许多字段的消息,并且最多只能同时设置一个字段,则可以使用oneof
功能强制执行此行为并节省内存。
oneof
里面可以包含许多数据类型,但是只会被设置一个数据类型,且设置了一个oneof
字段后会清空掉前面所设置的其他oneof
成员,所有这样可以节省许多内存。
集成netty
Initializer
public class MyProtoInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
//解码器,通过Google Protocol Buffers序列化框架动态的切割接收到的ByteBuf
pipeline.addLast(new ProtobufVarint32FrameDecoder());
//服务端\客户端接收的是DataInfo对象,所以这边将接收对象进行解码生产实列
pipeline.addLast(new ProtobufDecoder(DataInfo.MyMessage.getDefaultInstance()));
//Google Protocol Buffers编码器
pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
//Google Protocol Buffers编码器
pipeline.addLast(new ProtobufEncoder());
pipeline.addLast(new