助力软件开发企业降本增效 PHP / java源码系统,只需一次付费,代码终身使用! 广告
## 一、概述 Netty 是一个利用 Java 基于NIO(Nonblocking I/O,非阻塞IO,相对的,阻塞IO即BIO)的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架; ![](https://img.kancloud.cn/85/52/8552db7ceabc450d9e0eb8db689155d6_592x348.png) 比起直接用NIO编程,用Netty要简化很多; 1. **并发高** 2. **传输快** 3. **封装好** ## 二、核心概念 ### **Channel** 数据传输流,与channel相关的概念有以下四个,上一张图让你了解netty里面的Channel; ![](https://img.kancloud.cn/52/50/525049c2d106a975c0e9bdfc7a96780b_751x319.png) * **Channel**,表示一个连接,可以理解为每一个请求,就是一个Channel; * **ChannelHandler**,核心处理业务就在这里,用于处理业务请求,分为ChannelInboundHandler输入数据处理器和ChannelOutboundHandler输出业务处理器; * **ChannelHandlerContext**,用于传输业务数据; * **ChannelPipeline**,用于保存处理过程需要用到的ChannelHandler和ChannelHandlerContext; >[danger] 交互流程; > 1. 事件传递给 ChannelPipeline 的第一个 ChannelHandler > 2. ChannelHandler 通过关联的 ChannelHandlerContext 传递事件给 ChannelPipeline 中的 下一个; > 3. ChannelHandler 通过关联的 ChannelHandlerContext 传递事件给 ChannelPipeline 中的 下一个,一直到最后一个处理完; ### **ByteBuf** ByteBuf是一个存储字节的容器,最大特点就是**使用方便**,它既有自己的读索引和写索引,方便你对整段字节缓存进行读写,也支持get/set,方便你对其中每一个字节进行读写; ![](https://img.kancloud.cn/d2/20/d2204925603d5e4b8f113289d70511ac_558x181.png) ### **Codec** 包括Decoder和Encoder; Netty中的编码/解码器,通过他你能完成字节与pojo、pojo与pojo的相互转换,从而达到自定义协议的目的,在Netty里面最有名的就是HttpRequestDecoder和HttpResponseEncoder了; 它们,实际上就是对应这**ChannelInboundHandler和ChannelOutboundHandler**,别用于在数据流进来的时候将字节码转换为消息对象和数据流出去的时候将消息对象转换为字节码; ## 三、快速入门 用一个简单的HttpServer实现例子作为示范; 只需要两个类,其中启动类负责启动(BootStrap)和main方法,另外是ChannelHandler,负责具体的业务逻辑; ``` public class NettySampleServer { private static Logger logger = LoggerFactory.getLogger(NettySampleServer.class); public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true).childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new NettySampleServerHandler()); } }); logger.info("server is ready......"); ChannelFuture channelFuture = bootstrap.bind(6666).sync(); channelFuture.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } } ``` ``` public class NettySampleServerHandler extends ChannelInboundHandlerAdapter { private static Logger logger = LoggerFactory.getLogger(NettySampleServerHandler.class); @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf byteBuf = (ByteBuf) msg; logger.info("收到[{}]消息[{}]", ctx.channel().remoteAddress(), byteBuf.toString(CharsetUtil.UTF_8)); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush(Unpooled.copiedBuffer("已收到", CharsetUtil.UTF_8)); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } } ```