深入学习Netty(4)——Netty编程入门
前言
从学习过BIO、NIO、AIO编程之后,就能很清楚Netty编程的优势,为什么选择Netty,而不是传统的NIO编程。本片博文是Netty的一个入门级别的教程,同时结合时序图与源码分析,以便对Netty编程有更深的理解。
在此博文前,可以先学习了解前几篇博文:
- 深入学习Netty(1)——传统BIO编程
- 深入学习Netty(2)——传统NIO编程
- 深入学习Netty(3)——传统AIO编程
参考资料《Netty In Action》、《Netty权威指南》(有需要的小伙伴可以评论或者私信我)
博文中所有的代码都已上传到Github,欢迎Star、Fork
一、服务端创建
Netty屏蔽了NIO通信的底层细节,减少了开发成本,降低了难度。ServerBootstrap可以方便地创建Netty的服务端
1.服务端代码示例
public void bind (int port) throws Exception {
// NIO 线程组
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
// Java序列化编解码 ObjectDecoder ObjectEncoder
// ObjectDecoder对POJO对象解码,有多个构造函数,支持不同的ClassResolver,所以使用weakCachingConcurrentResolver
// 创建线程安全的WeakReferenceMap对类加载器进行缓存SubReqServer
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
// 半包处理 ProtobufVarint32FrameDecoder
socketChannel.pipeline().addLast(new ProtobufVarint32FrameDecoder());
// 添加ProtobufDecoder解码器,需要解码的目标类是SubscribeReq
socketChannel.pipeline().addLast(
new ProtobufDecoder(SubscribeReqProto.SubscribeReq.getDefaultInstance()));
socketChannel.pipeline().addLast(new ProtobufVarint32LengthFieldPrepender());
socketChannel.pipeline().addLast(new ProtobufEncoder());
socketChannel.pipeline().addLast(new SubReqServerHandler());
}
});
// 绑定端口,同步等待成功
ChannelFuture f = bootstrap.bind(port).sync();
// 等待所有服务端监听端口关闭
f.channel().closeFuture().sync();
} finally {
// 优雅退出,释放线程池资源
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}


