Protobuf多协议

不打扰是莪最后的温柔 提交于 2019-11-26 20:45:49

上一篇只有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、服务端输出

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!