Netty集成Google ProtoBuf

2019-08-19  本文已影响0人  手心里得温柔

集成步骤:
1、编写 .proto 文件
编写 netty_demo.proto 文件,内容如下

syntax ="proto2";

package com.github.mgljava.protobuf.netty;

option optimize_for = SPEED;
option java_package = "com.github.mgljava.protobuf.netty";
option java_outer_classname="NettyDemoData";
// 请求对象
message RequestUser{
  optional string user_name = 1;
  optional int32 age = 2;
  optional string password = 3;
}
// 响应对象
message ResponseBank{
  optional string bank_no = 1;
  optional double money = 2;
  optional string bank_name=3;
}

2、根据ProtoBuf的工具来生成 Java的实体类: NettyDemoData.java

// 参数介绍:第一个参数src/main/java/ 代表的是要将代码生成后放到哪里,第二个参数src/protobuf/netty_demo.proto是需要告诉 protoc 自定义的 .proto 文件在哪里
protoc --java_out=src/main/java/ src/protobuf/netty_demo.proto

protoc 是ProtoBuf提供的,根据 .proto 文件生成代码的工具,这里使用到了 --java_out 选项,更多选项可以使用 protoc -h 得到。

3、编写Netty的服务端

public class NettyDemoServer {

  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 ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) {
              ChannelPipeline pipeline = ch.pipeline();
              pipeline.addLast(new ProtobufVarint32FrameDecoder());
              // 解码器,将数据解码成 RequestUser 对象
              pipeline.addLast(new ProtobufDecoder(NettyDemoData.RequestUser.getDefaultInstance()));
              pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
              pipeline.addLast(new ProtobufEncoder());

              pipeline.addLast(new NettyDemoServerHandler());
            }
          });

      ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
      channelFuture.channel().closeFuture().sync();
    } finally {
      bossGroup.shutdownGracefully();
      workerGroup.shutdownGracefully();
    }
  }
}

public class NettyDemoServerHandler extends SimpleChannelInboundHandler<RequestUser> {

  @Override
  protected void channelRead0(ChannelHandlerContext ctx, RequestUser requestUser) {
    System.out.println("姓名:" + requestUser.getUserName());
    System.out.println("年龄:" + requestUser.getAge());
    System.out.println("密码:" + requestUser.getPassword());

    NettyDemoData.ResponseBank response = NettyDemoData.ResponseBank.newBuilder().setBankName("银行")
        .setBankNo("123456789987654321").setMoney(100.00).build();

    ctx.channel().writeAndFlush(response);
  }
}

4、编写Netty的客户端

public class NettyDemoClient {

  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 ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) {
              ChannelPipeline pipeline = ch.pipeline();

              pipeline.addLast(new ProtobufVarint32FrameDecoder());
              // 解码器,将数据解码成 ResponseBank 对象
              pipeline.addLast(new ProtobufDecoder(NettyDemoData.ResponseBank.getDefaultInstance()));
              pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
              pipeline.addLast(new ProtobufEncoder());
              pipeline.addLast(new NettyDemoClientHandler());
            }
          });

      ChannelFuture channelFuture = bootstrap.connect("localhost", 8899).sync();
      channelFuture.channel().closeFuture().sync();

    } finally {
      eventLoopGroup.shutdownGracefully();
    }
  }
}

public class NettyDemoClientHandler extends SimpleChannelInboundHandler<ResponseBank> {

  @Override
  protected void channelRead0(ChannelHandlerContext ctx, ResponseBank msg) {
    System.out.println("账号:" + msg.getBankNo());
    System.out.println("名称:" + msg.getBankName());
    System.out.println("存款:" + msg.getMoney());
  }

  @Override
  public void channelActive(ChannelHandlerContext ctx) {
    NettyDemoData.RequestUser user = NettyDemoData.RequestUser.newBuilder()
        .setUserName("张三")
        .setAge(20)
        .setPassword("123456").build();
    ctx.channel().writeAndFlush(user);
  }
}

5、测试
服务器端输出:

在这里插入图片描述
客户端输出:
在这里插入图片描述
上一篇下一篇

猜你喜欢

热点阅读