• Protobuf多协议


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

  • 相关阅读:
    JavaScript数组方法--includes、indexOf、lastIndexOf
    JavaScript数组方法--flat、forEach、map
    JavaScript数组方法--filter、find、findIndex
    bootstrap-14
    bootstrap-13
    bootstrap-12
    bootstrap-11
    bootstrap-10
    bootstrap-9
    bootstrap-8
  • 原文地址:https://www.cnblogs.com/linlf03/p/11332972.html
Copyright © 2020-2023  润新知