Netty(五)序列化protobuf在netty中的使用

protobuf是google序列化的工具,主要是把数据序列化成二进制的数据来传输用的。它主要优点如下:

1.性能好,效率高;

2.跨语言(java自带的序列化,不能跨语言)

protobuf参考文档:Protobuf详解

 其实,在netty中使用Protobuf需要注意的是:

 protobufDecoder仅仅负责编码,并不支持读半包,所以在之前,一定要有读半包的处理器。

 有三种方式可以选择:

  1. 使用netty提供ProtobufVarint32FrameDecoder
  2. 继承netty提供的通用半包处理器 LengthFieldBasedFrameDecoder
  3. 继承ByteToMessageDecoder类,自己处理半包

Server源码部分:

 1         try {
 2             // ServerBootstrap 类,是启动NIO服务器的辅助启动类
 3             ServerBootstrap b = new ServerBootstrap();
 4             b.group(bossGroup,WorkerGroup)
 5                     .channel(NioServerSocketChannel.class)
 6                     .option(ChannelOption.SO_BACKLOG,1024)
 7                     .childHandler(new ChannelInitializer<SocketChannel>() {
 8                         @Override
 9                         public void initChannel(SocketChannel ch){
10                             // protobufDecoder仅仅负责编码,并不支持读半包,所以在之前,一定要有读半包的处理器。
11                             // 有三种方式可以选择:
12                             // 使用netty提供ProtobufVarint32FrameDecoder
13                             // 继承netty提供的通用半包处理器 LengthFieldBasedFrameDecoder
14                             // 继承ByteToMessageDecoder类,自己处理半包
15 
16                             // 半包的处理
17                             ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
18                             // 需要解码的目标类
19                             ch.pipeline().addLast(new ProtobufDecoder(PersonProbuf.Person.getDefaultInstance()));
20 
21                             ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
22 
23                             ch.pipeline().addLast(new ProtobufEncoder());
24 
25                             ch.pipeline().addLast(new ReqServerHandler());
26                         }
27                     });
28 
29             // 绑定端口,同步等待成功
30             ChannelFuture f= b.bind(port).sync();
31 
32             // 等待服务端监听端口关闭
33             f.channel().closeFuture().sync();
34         }finally {
35             // 释放线程池资源
36             bossGroup.shutdownGracefully();
37             WorkerGroup.shutdownGracefully();
38         }

client源码部分:

 1 try {
 2             // Bootstrap 类,是启动NIO服务器的辅助启动类
 3             Bootstrap b = new Bootstrap();
 4             b.group(group).channel(NioSocketChannel.class)
 5                     .option(ChannelOption.TCP_NODELAY,true)
 6                     .handler(new ChannelInitializer<SocketChannel>() {
 7                         @Override
 8                         public void initChannel(SocketChannel ch)
 9                                 throws Exception{
10                             //
11                             ch.pipeline().addLast(new ProtobufVarint32FrameDecoder());
12 
13                             ch.pipeline().addLast(new ProtobufDecoder(PersonProbuf.Person.getDefaultInstance()));
14                             ch.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
15                             ch.pipeline().addLast(new ProtobufEncoder());
16                             ch.pipeline().addLast(new ReqClientHandler());
17 
18                         }
19                     });
20 
21             // 发起异步连接操作
22             ChannelFuture f= b.connect(host,port).sync();
23 
24             // 等待客服端链路关闭
25             f.channel().closeFuture().sync();
26         }finally {
27             group.shutdownGracefully();
28         }

源码下载

源码在src/main/java/Serialization_ProtoBuf下,分为客户端和服务端,他们的代码基本和Netty入门章节的代码类似,只是增加了Protobuf相关的解码器使用。ProtoBuf文件下,是相关的protobuf的windows下的代码生成器.

GitHub地址:https://github.com/orange1438/Netty_Course

 
作者:orange1438
出处:http://www.cnblogs.com/orange1438/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/orange1438/p/5075318.html