一盏灯, 一片昏黄; 一简书, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。
基于netty构建服务的基本步骤
我们通过netty实现一个Http服务器的功能,来说明通过netty构建的Server基本步骤。
学习一个新的知识点,都是通过Hello world开始的,对于netty的学习写一个Hello world程序不像写其他程序那么简单,这里涉及很多非常重要的组件,比如ChannelHandler、EeventLoopGroup、ChannelPipeline等,这些组件随着后续不断学习再一一分析其实现原理。
基于netty构建Http服务器基本步骤实践:
首先我们定义两个线程组 也叫做事件循环组
EevetLoopGroup bossGroup = new NioEevetLoopGroup();
EevetLoopGroup workerGroup = new NioEevetLoopGroup();
为什么定义两个线程组,实际上一个线程组也能完成所需的功能,不过netty建议我们使用两个线程组,分别具有不同的职责。bossGroup目的是获取客户端连接,连接接收到之后再将连接转发给workerGroup去处理。
定义一个轻量级的启动服务类
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, wokrerGroup).channel(NioServerSocketChannel.class).childHandler(null);
// 服务启动后通过绑定到8899端口上,返回ChannelFuture。
ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
channelFuture.channel().closeFuture().sync();
![类图](http://upload-images.jianshu.io/upload_images/3609866-5e0eaca91e925ef4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
3. 通过ChannelPipeline初始化处理器,类似于拦截器Chain,当客户端首次连接后即调用initChannel方法完成初始化动作。
[示例代码]
public class TestServerInitializer extends ChannelInitializer{
// 初始化器,服务端启动后会自动调用这个方法,它是一个回调方法。
@Override protected void initChannel(SocketChannel ch) throws Exception {
System.out.println("initChannel invoked... "); // 有客户端连接就会执行.
ChannelPipeline channelPipeline = ch.pipeline(); // pipeline一个管道里面可以有很多的ChannelHandler,相当于包含很多个拦截器。
// 添加处理器,可以添加多个,并且可以将处理器放到pipeline管道的不同位置上。
channelPipeline.addLast("httpServerCodec", new HttpServerCodec()); //HttpServerCodec也是一个很重要的组件.
channelPipeline.addLast("httpServerHandler", new TestHttpServerHandler()); // 自定义处理器
}
}
4. 创建自定义处理器,通常继承SimpleChannelInboundHandler, 该处理器覆写channelRead0方法,该方法负责请求接入,读取客户端请求,发送响应给客户端。
[示例代码]
public class TestHttpServerHandler ext