官网地址:https://netty.io/
Netty是一个异步事件驱动的网络应用框架用于快速开发可维护的高性能协议服务器和客户端。
Netty是一个NIO客户端服务器框架,它支持快速和容易地开发网络应用程序,如协议服务器和客户端。它极大地简化和流线型网络编程,如TCP和UDP套接字服务器。
“快速和简单”并不意味着最终的应用程序将受到可维护性或性能问题的影响。Netty经过精心设计,积累了许多协议的实现经验,如FTP、SMTP、HTTP和各种基于二进制和文本的遗留协议。因此,Netty成功地找到了一种方法,在不妥协的情况下实现开发的易用性、性能、稳定性和灵活性。
特性
设计
- 各种传输类型的统一API——阻塞和非阻塞套接字
- 基于一个灵活和可扩展的事件模型,它允许清晰的关注点分离
- 高度可定制的线程模型——单个线程,一个或多个线程池,如SEDA
- 真正的无连接数据报套接字支持(从3.1开始)
易用性
- 文档丰富的Javadoc、用户指南和示例
- 没有其他依赖,JDK 5 (Netty 3.x)或6 (Netty 4.x)就足够了,注意:一些组件(如HTTP/2)可能有更多的需求。更多信息请参考需求页面。
性能
- 更好的吞吐量,更低的延迟
- 更少的资源消耗
- 尽量减少不必要的内存拷贝
安全
- 完整的SSL/TLS和StartTLS支持
社区
- 尽早发布,经常发布
- 作者自2003年以来一直在编写类似的框架,他仍然认为您的反馈非常宝贵!
前言! ! ! ! !
问题
现在我们使用通用的应用程序或库相互通信。例如,我们经常使用HTTP客户端库从web服务器检索信息,并通过web服务调用远程过程调用。然而,通用协议或其实现有时不能很好地伸缩。这就像我们不使用通用HTTP服务器来交换大型文件、电子邮件消息和几乎实时的消息(如财务信息和多人游戏数据)一样。所需要的是专门用于特殊目的的高度优化的协议实现。例如,您可能希望实现一个针对基于ajax的聊天应用程序、媒体流或大文件传输进行优化的HTTP服务器。您甚至可以设计和实现一个完全适合您需要的全新协议。另一种不可避免的情况是,您必须处理遗留的专有协议,以确保与旧系统的互操作性。在这种情况下,重要的是在不牺牲最终应用程序的稳定性和性能的情况下,我们能够多快地实现该协议。
解决方案
Netty项目致力于提供异步事件驱动的网络应用框架和工具,以快速开发可维护的高性能·高可伸缩性协议服务器和客户端。
换句话说,Netty是一个NIO客户端服务器框架,它支持快速和容易地开发网络应用程序,如协议服务器和客户端。它极大地简化和流线型网络编程,如TCP和UDP套接字服务器开发。
“快速和简单”并不意味着最终的应用程序将受到可维护性或性能问题的影响。Netty经过精心设计,吸取了许多协议(如FTP、SMTP、HTTP和各种基于二进制和文本的遗留协议)实现的经验。因此,Netty成功地找到了一种方法,在不妥协的情况下实现开发的易用性、性能、稳定性和灵活性。
一些用户可能已经发现了其他声称具有相同优势的网络应用程序框架,您可能想问Netty与他们有什么不同。答案是它所基于的哲学。Netty从一开始就为您提供API和实现方面最舒适的体验。这不是什么有形的东西,但当你阅读本指南并与Netty一起玩时,你会意识到这种哲学将使你的生活更容易。
开始
本章围绕Netty的核心结构进行了介绍,并提供了一些简单的示例,以便您快速入门。在本章结束时,您将能够立即在Netty上编写客户机和服务器。
如果您更喜欢自顶向下的学习方法,那么您可能希望从第2章“体系结构概述”开始,然后回到这里。
在开始之前
运行本章示例的最低要求只有两个;Netty和JDK 1.6或以上的最新版本。Netty的最新版本可以从项目下载页面获得。要下载JDK的正确版本,请参考您首选的JDK供应商的网站。
在阅读时,您可能对本章介绍的类有更多的问题。如有需要,请参阅API参考资料。为了方便您,本文中的所有类名都链接到在线API引用。另外,请不要犹豫与Netty project社区联系,如果有任何错误信息、语法错误和打印错误,以及您是否有改进文档的好主意,请告诉我们。
编写一个可退出的服务器
世界上最简单的协议不是“你好,世界!”但退出。它是一个丢弃任何接收到的数据而没有任何响应的协议。
要实现丢弃协议,惟一需要做的就是忽略所有接收到的数据。让我们直接从处理程序实现开始,它处理Netty生成的I/O事件。
package io.netty.example.discard; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; /** * Handles a server-side channel. */ public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1) @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2) // Discard the received data silently. ((ByteBuf) msg).release(); // (3) } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4) // Close the connection when an exception is raised. cause.printStackTrace(); ctx.close(); } }
- DiscardServerHandler扩展了ChannelInboundHandlerAdapter,它是ChannelInboundHandler的实现。ChannelInboundHandler提供了各种可以重写的事件处理程序方法。现在,仅仅扩展ChannelInboundHandlerAdapter就足够了,而不必自己实现处理程序接口。
- 我们在这里重写channelRead()事件处理程序方法。无论何时从客户端接收到新数据,都会使用接收到的消息调用此方法。在本例中,接收到的消息类型是ByteBuf。
- 要实现丢弃协议,处理程序必须忽略接收到的消息。ByteBuf是一个引用计数的对象,必须通过release()方法显式地释放它。请记住,释放传递给处理程序的引用计数对象是处理程序的责任。通常,channelRead()处理程序方法是这样实现的:
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) { try { // Do something with msg } finally { ReferenceCountUtil.release(msg); } }
- exceptionCaught()事件处理程序方法在Netty由于I/O错误引发异常或处理程序实现在处理事件时由于异常引发异常时调用。在大多数情况下,应该记录捕获的异常,并在这里关闭它的关联通道,尽管该方法的实现可能不同,这取决于您希望如何处理异常情况。例如,您可能希望在关闭连接之前发送带有错误代码的响应消息。
到目前为止一切顺利。我们