Netty是一个提供 asynchronous event-driven (异步风波驱动)的网路应用框架,是一个用以迅速开发高性能、高可靠性合同的服务器跟客户端。换句话说,Netty 是一个 NIO 客户端服务器框架,使用它可以迅速简略地开发网路应用程序,比如服务器跟客户端的合同。Netty 大大简化了网路程序的开发过程例如 TCP 和 UDP 的 socket 服务的开发。 “快速跟简略”并不意味着应用程序会有难维护跟功耗低的问题,Netty 是一个悉心设计的框架,它从许多合同的实现中吸收了太多的经验诸如 FTP、SMTP、HTTP、许多二进制跟基于文本的传统合同.因此,Netty 已经成功地找到一个形式,在不失灵活性的前提下去实现开发的简易性,高性能,稳定性。推荐了解黑马程序员java轮训课程。
围绕Netty 的核心构架,通过简略的样例带你迅速入门。当你写完本章节,你立马就可以用 Netty 写出一个客户端跟服务器。
开始之前
在开始之前我们先说明下开发环境微端服务器,我们使用netty-4.1.30这个版本,jdk使用1.8及以上版本。
<dependency>
<groupId>io.nettygroupId>
<artifactId>netty-allartifactId>
<version>4.1.30.Finalversion>
dependency>
先来个遗弃服务
世上最简略的合同不是'Hello, World!' 而是 DISCARD(丢弃)。这个合同将要扔掉任何收到的数据,而不响应。 为了实现 DISCARD 协议,你只需忽视所有收到的数据。让我们从 handler (处理器)的实现开始,handler 是由Netty 生成拿来处理 I/O 事件的。
先争创一个处理器
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
try {
// Do something with msg
} finally {
ReferenceCountUtil.release(msg);
}
}
(4)exceptionCaught()事件处理方式是当出现Throwable对象就会被读取,即当Netty因为IO错误或则处理器在处理丑闻时抛出的异常时。在大部分状况下,捕获的异常应当被记录出来而且把关联的 channel 给关掉掉。然而这个方式的处理方法会在碰到不同异常的状况下有不同的实现,比如你或许想在关掉连结之前发送一个错误码的响应消息。
编写服务端代码
目前为止一切都还不错,我们早已实现了DISCARD服务器的一半功能,剩下的还要撰写一个main()方法来启动服务端的DiscardServerHandler 。
package com.netty.first;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
* 丢弃任何进入的数据
*/
public class DiscardServer {
private int port;
public DiscardServer(int port) {
this.port = port;
}
public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // (3)
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new DiscardServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128) // (5)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
// 绑定端口,开始接收进来的连接
ChannelFuture f = b.bind(port).sync(); // (7)
// 等待服务器 socket 关闭 。
// 在这个例子中,这不会发生,但你可以优雅地关闭你的服务器。
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
} else {
port = 8080;
}
new DiscardServer(port).run();
}
}