Netty-ProtoBuf编码解码--多种类型传输

  • proto文件

syntax = "proto3";//声明使用proto3的语法
option optimize_for=SPEED;//加快解析
option java_package = "com.zeng.nio.netty.protoBuf2";//指定包名
option java_outer_classname = "DataInfo";//指定生成java类名

message Model{
    //申明一个枚举类型
    enum ModelType{
        StudentType =0;
        WorkerType=1;
    }

    //申明一个属性
    ModelType dataType=1;

    //Student和Worker属性一次只能传输一个
    oneof dataBody{
        Student student=2;
        Worker worker=3;
    }
}
//申明一个类
message Student {
    //申明int类型的属性名及次序
    int32 id = 1;
    string name = 2;
    string email = 3;
}
message Worker {
    int32 id = 1;
    string name = 2;
    int32 age = 3;
}
  • 编译proto文件

  1. 编译命令:protoc --java_out=. proto/DataInfo.proto
  2. 把 DataInfo.java放到项目中 
  • 客户端发送及接收

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;

public class Client {
    public static void main(String[] args) {
        EventLoopGroup group=new NioEventLoopGroup();

        try {
            Bootstrap bootstrap=new Bootstrap()
                    .group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            //1 编码器 解码器
                            pipeline.addLast(new ProtobufEncoder());
                            pipeline.addLast(new ProtobufDecoder(DataInfo.Model.getDefaultInstance()));

                            //2 自定义处理器:通道连接成功后发送pojo对象消息
                            pipeline.addLast(new SimpleChannelInboundHandler(){
                                @Override
                                public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                    //3.1 给服务器端发送student类型的信息
                                    DataInfo.Model msg = DataInfo.Model.newBuilder()
                                            .setDataType(DataInfo.Model.ModelType.StudentType)
                                            .setStudent(
                                                    DataInfo.Student.newBuilder()
                                                            .setId(0)
                                                            .setName("student")
                                                            .setEmail("[email protected]")
                                                            .build())
                                            .build();
                                    ctx.writeAndFlush(msg);
                                }

                                @Override
                                protected void channelRead0(ChannelHandlerContext ctx, DataInfo.Model msg) throws Exception {
                                    //3.2 从服务器端收取信息
                                    DataInfo.Model.ModelType dataType = msg.getDataType();
                                    switch (dataType){
                                        case StudentType:
                                            DataInfo.Student student = msg.getStudent();
                                            System.out.println("id:"+student.getId()+" name:"+student.getName()+" email:"+student.getEmail());
                                            break;
                                        case WorkerType:
                                            DataInfo.Worker worker = msg.getWorker();
                                            System.out.println("id:"+worker.getId()+" name:"+worker.getName()+" age:"+worker.getAge());
                                    }
                                }
                            });
                        }
                    });
            ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 9999).sync();
            channelFuture.addListener(future -> {
                if (future.isSuccess())
                    System.out.println("ok");
                else
                    System.out.println("no");
            });
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            group.shutdownGracefully();
        }
    }
}
  •  服务端接收及回复消息

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;

public class Server {
    public static void main(String[] args){
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap()
                    .group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            //1 编码器 解码器
                            pipeline.addLast(new ProtobufEncoder());
                            pipeline.addLast(new ProtobufDecoder(DataInfo.Model.getDefaultInstance()));

                            //2 自定义处理器:通道连接成功后接收pojo对象
                            pipeline.addLast(new SimpleChannelInboundHandler(){
                                @Override
                                protected void channelRead0(ChannelHandlerContext ctx, DataInfo.Model msg) throws Exception {
                                    //3.1 根据类型输出收到的客户端的信息
                                    DataInfo.Model.ModelType dataType = msg.getDataType();
                                    switch (dataType){
                                        case StudentType:
                                            DataInfo.Student student = msg.getStudent();
                                            System.out.println("id:"+student.getId()+" name:"+student.getName()+" email:"+student.getEmail());
                                            break;
                                        case WorkerType:
                                            DataInfo.Worker worker = msg.getWorker();
                                            System.out.println("id:"+worker.getId()+" name:"+worker.getName()+" age:"+worker.getAge());
                                    }

                                    //3.2 给客户端回复worker类型的信息
                                    DataInfo.Model worker = DataInfo.Model.newBuilder()
                                            .setDataType(DataInfo.Model.ModelType.WorkerType)
                                            .setWorker(
                                                    DataInfo.Worker.newBuilder()
                                                            .setId(1)
                                                            .setName("worker")
                                                            .setAge(30)
                                                            .build())
                                            .build();
                                    ctx.writeAndFlush(worker);
                                }
                            });
                        }
                    });

            ChannelFuture channelFuture = serverBootstrap.bind(9999).sync();
            channelFuture.addListener(future -> {
                if (future.isSuccess())
                    System.out.println("ok");
                else
                    System.out.println("no");
            });
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

 

你可能感兴趣的:(Netty,NIO)