1、首先学习Netty中几个重要的组建:
3、如何配置一个Netty应用。
EventLoops:
EventLoops
的目的是为Channel处理IO操作,一个EventLoop可以为多个Channel服务。
Bootstrap:Bootstrap是一个用于启动NIO(客户端)的辅助启动类。ServerBootstrap这是针对于服务端的,一个Netty应用通常由一个Bootstrap开始,负责配置整个Netty程序,串联起各个组件。
Handler:Handler组件是用来支持各种协议和处理数据的方式,比如连接、数据接收、异常、数据转换等。
Channel:Channel代表了一个Socket链路,或者其他和IO操作相关的组件,他和EventLoop一起用来IO处理。
Future:在Netty中所有的IO操作都是异步的,所以消息不能立刻被正确处理,可以等待这个执行完或者直接注册一个监听,具体通过Future和ChannelFutures注册监听,不管结果怎么样都会返回一个ChannelFuture。
ChannelPipeline:一个Netty应用基于ChannelPipeline机制,这种机制需要依赖于EventLoop和EventLoopGroup,因为他们三个都是和事件处理相关。
2、Netty处理连接请求和业务逻辑
a)、Netty是一个非阻塞的、事件驱动的、网络编程框架,很容易理解Netty会用线程来处理IO事件。
b)、一个Channl会对应一个EventLoop,而一个EventLoop会对应一个线程,就是说一个线程在负责一个Channel的IO操作。
服务端:
// 配置服务端的NIO线程组
EventLoopGroup bossGroup = new NioEventLoopGroup(); // 用于与客户端进行连接
EventLoopGroup workerGroup = new NioEventLoopGroup(); // 用于对IO的读写操作
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChildChannelHandler());
// 绑定端口,同步等待客户端的连接
ChannelFuture f = b.bind(8080).sync();
// 等待服务端监听端口关闭
f.channel().closeFuture().sync();
} finally {
// 优雅退出,释放线程池资源
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
/*
ChannelInitializer,当一个链接建立时,我们需要知道怎么来接收或者发送数据,当然,我们有各种各样的Handler实现来处理它,那么ChannelInitializer便是用来配置这些Handler,它会提供一个ChannelPipeline,并把Handler加入到ChannelPipeline
*/
private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
//
TimeServerHandler类继承ChannelHandlerAdapter类,用来对数据接收和发送。
sc.pipeline().addLast(new TimeServerHandler());
}
}
客户端:
// 配置客户端NIO线程组
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)
throws Exception {
ch.pipeline().addLast(new TimeClientHandler());
//
TimeClientHandler类继承ChannelHandlerAdapter类,用来对数据接收和发送。
}
});
// 发起异步连接操作
ChannelFuture f = b.connect(127.0.0.1, 8080).sync();
// 当代客户端链路关闭
f.channel().closeFuture().sync();
} finally {
// 优雅退出,释放NIO线程组
group.shutdownGracefully();
}
这是一个简单的实例,希望对你有帮助。