Netty對Protocol Buffer多協議的支持(八)
阿新 • • 發佈:2017-06-19
center end pipe 使用 read 回來 .sh cli outer
Netty對Protocol Buffer多協議的支持(八)
一.背景
在上篇博文中筆者已經用代碼演示了如何在netty中使用Protocol Buffer,然而細心的用戶可能會發現一個明顯的不足之處就是,我們的Handler只能處理一種特定的類型,而我們的項目中又不可能只有一種類型,那麽這個問題該怎麽解決了?多的不說,筆者直接上代碼。
二.代碼實現
2.1 message的編寫
syntax = "proto2"; package com.rsy.netty.protobuf; option java_package = "com.rsy.netty.protobuf"; option java_outer_classname= "DataInfo"; message Datas{ enum DataType { personType = 1; dogType = 2; } required DataType data_type = 1; oneof type_data{ Person person = 2; Dog dog = 3; } } message Person{ required int32 id = 1; optional string name = 2; enum Gender { male = 1; female = 2; } optional Gender gender = 3; } message Dog { required float height = 1; optional string color = 2; optional int64 age = 3; }
2.2 生成Java代碼,在此不再贅述。
2.3 服務端啟動代碼
public class ServerTest { public static void main(String[] args) throwsException { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try{ ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new ServerChannelInitilizer()); ChannelFuture channelFuture = serverBootstrap.bind(8989).sync(); channelFuture.channel().closeFuture().sync(); }finally{ bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
2.4 服務端通道初始化代碼
public class ServerChannelInitilizer extends ChannelInitializer<SocketChannel>{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("protobufVarint32FrameDecoder", new ProtobufVarint32FrameDecoder()); pipeline.addLast("protobufDecoder", new ProtobufDecoder(DataInfo.Datas.getDefaultInstance())); pipeline.addLast("protobufVarint32LengthFieldPrepender", new ProtobufVarint32LengthFieldPrepender()); pipeline.addLast("protobufEncoder", new ProtobufEncoder()); pipeline.addLast("serverHandler", new ServerHandler()); } }
2.5 服務端Handler代碼
public class ServerHandler extends SimpleChannelInboundHandler<DataInfo.Datas>{ @Override protected void channelRead0(ChannelHandlerContext ctx, DataInfo.Datas msg) throws Exception { /** * 因為最先寫過來的是Person */ DataInfo.Person p = msg.getPerson(); System.out.println(msg.getDataType().toString()); System.out.println(p.getId()); System.out.println(p.getGender().toString()); System.out.println(p.getName()); DataInfo.Datas data = DataInfo.Datas.newBuilder() .setDataType(DataType.dogType) .setDog( DataInfo.Dog.newBuilder() .setAge(23) .setColor("紅色") .setHeight(3.5f) ).build(); ctx.writeAndFlush(data); } }
2.6 客戶端啟動代碼
public class ClientTest { public static void main(String[] args) throws Exception { EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); try{ Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class) .handler(new ClientChannelInitializer()); ChannelFuture channelFuture = bootstrap.connect("localhost", 8989).sync(); channelFuture.channel().closeFuture().sync(); }finally{ eventLoopGroup.shutdownGracefully(); } } }
2.7 客戶端通道初始化代碼
public class ClientChannelInitializer extends ChannelInitializer<SocketChannel>{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("protobufVarint32FrameDecoder", new ProtobufVarint32FrameDecoder()); pipeline.addLast("protobufDecoder", new ProtobufDecoder(DataInfo.Datas.getDefaultInstance())); pipeline.addLast("protobufVarint32LengthFieldPrepender", new ProtobufVarint32LengthFieldPrepender()); pipeline.addLast("protobufEncoder", new ProtobufEncoder()); pipeline.addLast("clientHandler", new ClientHandler()); } }
2.8 客戶端Handler處理代碼
public class ClientHandler extends SimpleChannelInboundHandler<DataInfo.Datas>{ @Override protected void channelRead0(ChannelHandlerContext ctx, DataInfo.Datas msg) throws Exception { /** * 服務端寫回來的是dog */ DataInfo.Dog dog = msg.getDog(); System.out.println(msg.getDataType().toString()); System.out.println(dog.getAge()); System.out.println(dog.getColor()); System.out.println(dog.getHeight()); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { DataInfo.Datas data = DataInfo.Datas.newBuilder() .setDataType(DataType.personType) .setPerson( DataInfo.Person.newBuilder() .setId(23) .setGender(Gender.female) .setName("zhangsan") ) .build(); ctx.writeAndFlush(data); } }
三.運行
運行服務端啟動代碼,再運行客戶端啟動代碼。
Netty對Protocol Buffer多協議的支持(八)