Netty对Protocol Buffer多协议的支持proto3

1:Protocol Buffers介绍
        Protocol Buffers(Protobuf)是Google推出的语言无关,平台无关的可扩展机制,用于序列化结构数据。由于是一种二进制的序列化协议,并且数据结构做了相应优化,因此比传统的XML、JSON数据格式序列化后体积更小,传输更快。Protobuf有proto2和proto3两个版本,有着不同的数据格式定义,proto3更简单,支持更多的编程语言,在这里我们使用proto3版本。Protobuf使用了一个编译器,可根据.proto文件中定义的数据结构,自动生成各种语言的模板代码,方便使用。

2:在netty中使用多Protocol Buffer协议

       //配置Protobuf解码处理器,消息接收到了就会自动解码,ProtobufDecoder是netty自带的,Message是自己定义的Protobuf类
       pipeline.addLast("protobufDecoder",new ProtobufDecoder(AIConstructionProtobuf.ParentMessage.getDefaultInstance()));

       在netty中使用Protocol Buffer,有一个不足之处、Handler只能处理一种特定的类型,解码处是一个类,而我们的项目中又不可能只有一种类型,一个类,不可能写成Object类型,于是我们需要抽象一个Parent的对象。在每一帧数据里面增加一个 DataType类型。来统一解析。

 

syntax ="proto3";

package com.tieniu.miao.netty.sixthexample;

option optimize_for = SPEED;
option java_package = "com.tieniu.miao.netty.seventhexample";
option java_outer_classname="MyDataInfo";

message MyMessage {

    enum DataType{
        PeopleType = 0;
        DogType = 1;
        CatType = 2;
    }

     DataType data_type = 0;

    //oneof的意思:如果有多个可选字段,在某一个时刻只能只有一个值被设置,可以节省内存空间
    oneof dataBody {
        People people = 1;
        Dog dog = 2;
        Cat cat = 3;
    }
}

message People{
    optional string name = 1;
    optional int32 age = 2;
    optional string address = 3;
}

message Dog{
    optional string name = 1;
    optional string age = 2;
}

message Cat{
    optional string name = 1;
    optional string city = 2;
}

3:生成Java代码、把Mes.proto文件放到 create.cmd 同文件下、双击 create.cmd 下。即可生成java文件。

      


4:配置代码
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yuyuan.internet.modules.video.protobufvo.AIConstructionProtobuf;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timer;
 
/**
 * netty处理器配置
 * @author kokJuis
 * @version 1.0
 * @date 2016-9-30
 */
public class VideoServerInitializer extends ChannelInitializer<SocketChannel> {
 
    static Logger logger = LoggerFactory.getLogger(VideoServerInitializer.class);
    
    Timer timer;
 
    public VideoServerInitializer() {
        timer = new HashedWheelTimer();
    }
    
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        // ----Protobuf处理器,这里的配置是关键----
        pipeline.addLast("frameDecoder", new ProtobufVarint32FrameDecoder());// 用于decode前解决半包和粘包问题(利用包头中的包含数组长度来识别半包粘包)
        //配置Protobuf解码处理器,消息接收到了就会自动解码,ProtobufDecoder是netty自带的,Message是自己定义的Protobuf类
        pipeline.addLast("protobufDecoder",new ProtobufDecoder(MyDataInfo.ParentMessage.getDefaultInstance()));
        // 用于在序列化的字节数组前加上一个简单的包头,只包含序列化的字节长度。
        pipeline.addLast("frameEncoder",new ProtobufVarint32LengthFieldPrepender());
        //配置Protobuf编码器,发送的消息会先经过编码
        pipeline.addLast("protobufEncoder", new ProtobufEncoder());
        // ----Protobuf处理器END----
        pipeline.addLast("handler", new VideoServerHandler());//自己定义的消息处理器,接收消息会在这个类处理
        //pipeline.addLast("ackHandler", new AckServerHandler());//处理ACK
        pipeline.addLast("timeout", new IdleStateHandler(100, 0, 0,TimeUnit.SECONDS));//此两项为添加心跳机制,60秒查看一次在线的客户端channel是否空闲
        pipeline.addLast(new HeartBeatServerHandler());// 心跳处理handler
    }
    // pipeline.addLast("framer", new DelimiterBasedFrameDecoder(2 * 1024, Delimiters.lineDelimiter()));
    // pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
    // pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值