上一篇只有Person的message,若是多了一個message,如Dog,這樣就會有問題。java
解決方法: 定義多協議bootstrap
1、定義proto文件dom
syntax = "proto2"; package com.example.protobuf; option optimize_for = SPEED; option java_package = "com.example.sixthexample"; option java_outer_classname = "MyDataInfo"; message MyMessage{ enum DataType{ PersonType = 1; DogType = 2; CatType = 3; } required DataType data_type = 1; oneof dataBody{ Person person = 2; Dog dog = 3; Cat cat = 4; } } message Person{ optional string name = 1; optional int32 age = 2; optional string address = 3; } message Dog{ optional string name = 1; optional int32 age = 2; } message Cat{ optional string name = 1; optional string city = 2; }
而後用命令生成ide
D:\workspace\study\basic\netty_demo>protoc --java_out=src/main/java src/protobuf/Person2.protooop
2、客戶端代碼測試
一、TestClient 類,和上一篇同樣ui
public class TestClient { 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 TestClientInitializer()); ChannelFuture channelFuture = bootstrap.connect("localhost",8899).sync(); channelFuture.channel().closeFuture().sync(); }finally { eventLoopGroup.shutdownGracefully(); } } }
二、TestClientHandle 類spa
public class TestClientHandle extends SimpleChannelInboundHandler<MyDataInfo.Person> { // 對於客戶端來講,輸入來自控制檯 @Override protected void channelRead0(ChannelHandlerContext ctx, MyDataInfo.Person msg) throws Exception { } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { //客戶端啓動後,將消息發送給服務端 int randomInt = new Random().nextInt(3); MyDataInfo.MyMessage myMessage = null; if(0 == randomInt){ MyDataInfo.Person person = MyDataInfo.Person.newBuilder() .setName("張三").setAge(30).setAddress("上海").build(); myMessage = MyDataInfo.MyMessage.newBuilder() .setDataType(MyDataInfo.MyMessage.DataType.PersonType) .setPerson(person).build(); }else if(1 == randomInt){ MyDataInfo.Dog dog = MyDataInfo.Dog.newBuilder() .setName("一隻狗").setAge(10).build(); myMessage = MyDataInfo.MyMessage.newBuilder() .setDataType(MyDataInfo.MyMessage.DataType.DogType) .setDog(dog).build(); }else{ MyDataInfo.Cat dog = MyDataInfo.Cat.newBuilder() .setName("一隻貓").setCity("杭州").build(); myMessage = MyDataInfo.MyMessage.newBuilder() .setDataType(MyDataInfo.MyMessage.DataType.CatType) .setCat(dog).build(); } ctx.channel().writeAndFlush(myMessage); } }
三、TestClientInitializer 改變的地方,以下圖紅色部分3d
3、服務端日誌
一、TestServer 和上一篇同樣
public class TestServer { 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 TestServerInitializer()); ChannelFuture channelFuture = serverBootstrap.bind(8899).sync(); channelFuture.channel().closeFuture().sync(); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
二、TestServerHandle 類
public class TestServerHandle extends SimpleChannelInboundHandler<MyDataInfo.MyMessage> { @Override protected void channelRead0(ChannelHandlerContext ctx, MyDataInfo.MyMessage msg) throws Exception { System.out.println("---- 服務端接收到消息 ----"); MyDataInfo.MyMessage.DataType dataType = msg.getDataType(); if(dataType == MyDataInfo.MyMessage.DataType.PersonType){ MyDataInfo.Person person = msg.getPerson(); System.out.println(person.getName()); System.out.println(person.getAge()); System.out.println(person.getAddress()); }else if(dataType == MyDataInfo.MyMessage.DataType.DogType){ MyDataInfo.Dog dog = msg.getDog(); System.out.println(dog.getName()); System.out.println(dog.getAge()); }else { MyDataInfo.Cat cat = msg.getCat(); System.out.println(cat.getName()); System.out.println(cat.getCity()); } } }
三、TestServerInitializer 改變的地方,以下圖紅色部分
4、測試
一、啓動服務端
二、啓動多個客戶端
三、服務端輸出