[TOC] 在前面的章节中,我们学会了使用Java NIO进行长连接Server的开发。尽管NIO在通讯过程中有内存占用低等优点,但其在配置使用方面,没有框架提供的功能便捷。接下来,我们将学习使用流行的Socket通信框架,来实现长连接服务端的开发。 Server端建议使用框架: - Netty - Mina - QuickServer ## Netty简介 Netty作为一个高性能的NIO通信框架,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指的,已经得到了成百上千的商用项目验证。 > 面对新事物的时候,人们往往把它想得太难,拿起来看看,才知道它是咋般模样。 相比同步I/O简单直接的编程模型,异步I/O在编程模型上有较大的差异,对开发人员也有更高的要求,同时问题的定位也更为复杂。Netty是当前业界应用最广泛的Java开源异步框架。Netty 框架能显著降低异步开发的门槛,使开发人员聚焦业务逻辑,免于处理复杂的底层通信机制和线程模型,从而能够简单和快速地开发异步应用。时至今日,越来越多的国内公司开始使用Netty来构建应用,使用Netty的开发者也日益增加。 ### Netty的体系结构 ![](https://img.kancloud.cn/ce/71/ce71c68905b1528b3a49b6290b3b5264_558x267.png) 看下一下上面的这张图,概述了Netty的一些核心能力: - 传输服务支持NIO、BIO; - 协议支持HTTP、Google Protobuf、文本行、二进制、视频图像等; - 提供了OOM-Proof Thread Pool、SSL安全支持 - 支持Spring等容器的集成 - 其核心特征:可扩展的事件模型、统一的对接API、零拷贝能力的Byte Buffer。 ## 核心类 在使用 Netty 进行服务端程序开发时,主要涉及端口监听、EventLoop 线程池创建、NioServerSocketChannel 和 ChannelPipeline 初始化等。 ### channel channel的主要作用: - close(),关闭channel - closeFuture()用来处理channel的关闭 - sync(),同步等待channel关闭 - addListener(),异步等待channel关闭 - pipeline(),添加处理器 - write(),将数据写入channel,需要配合flush()才能将数据刷出 - writeAndFlush(),将数据写入并刷出 ### pipeline&handler > 顾名思义,pipeline是一条处理消息的流水线,每一条工序,都在pipeline中进行了定义。 ChannelHandler用来处理Channel上的业务事件,pipeline则把各种ChannelHandler连成一串。 ![](https://img.kancloud.cn/0a/c8/0ac8b8c051423ee8d317dab9e5c24c18_849x292.png) 在Reactor经典模型中,Reactor查询到NIO就绪的事件后,分发到Handler,由Handler完成NIO操作和计算的操作。Handler主要的操作为Channel缓存读、数据解码、业务处理、写Channel缓存,然后由Channel(代表client)发送到最终的连接终端。ChannelHandler分为两类: - 入站处理器(ChannelInboundHandlerAdapter):主要用来读取客户端数据 - 出战处理器(ChannelInboundHandlerAdapter):主要翻来对返回客户端的数据进加工 注意点: - pipeline中的入站处理器没有向channel中写入数据,出站处理器是不会被触发的。 - 前面的入站处理器需要调用`super.channelRead(ctx, msg)`或者`ctc.fireChannelRead(msg)`,消息才能向后方的入站处理器传递——所谓,“击鼓传花,不能有人偷懒”; - ChannelHandler的执行顺序:ChannelInboundHandlerAdapter是按添加顺序,ChannelInboundHandlerAdapter则与添加顺序相反。 ![](https://img.kancloud.cn/5b/e0/5be0ffb27c28838ed9a4383c1e07beca_989x253.png) #### `channel.writeAndFlush()`和`ctx.writeAndFlush()`区别 - `ctx.writeAndFlush()`,是从当前的handler,由后向前找出站处理器; - `channel.writeAndFlush()`,是从pipeline尾部开始,由后向前找出站处理器。 ### 关于深入学习 由于篇幅原因,本小册侧重于实际项目演练,关于深入学习Netty一些方法,大家供可以参考一下。 - 使用Netty开发基本网络应用程序 - 彻底理解阻塞、非阻塞的区别,并跟Netty、 NIO的编码联系起来 - 懂得多路复用在服务器开发时的优势,为什么在此基础上还要加多线程 - Netty中是如何实现异步的,异步处理的优势是什么 - Netty中是如何管理线程的,EventLoop 如何运作 - Netty中是如何管理内存的,ByteBuf特点和分配时机 - 看源码、调试的一些技巧,让自己也能去看、去跟源码