標籤:zha stat void throw dog 代碼實現 服務 ntc ios
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) throws Exception { 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多協議的支援(八)