上一篇只有Person的message,如果多了一个message,如Dog,这样就会有问题。
解决方法: 定义多协议
一、定义proto文件
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;
}
然后用命令生成
D:\workspace\study\basic\netty_demo>protoc --java_out=src/main/java src/protobuf/Person2.proto
二、客户端代码
1、TestClient 类,和上一篇一样
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();
}
}
}
2、TestClientHandle 类
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);
}
}
3、TestClientInitializer 改变的地方,如下图红色部分

三、服务端
1、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();
}
}
}
2、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());
}
}
}
3、TestServerInitializer 改变的地方,如下图红色部分

四、测试
1、启动服务端
2、启动多个客户端
3、服务端输出

原文:https://www.cnblogs.com/linlf03/p/11332972.html