【第2篇】Netty与Http执行流程与重要组件
2019-05-13 本文已影响0人
爱学习的蹭蹭
1、Netty与Http的实现关键类摘要
- Netty不是遵循Http的Servlet标准规范进行实现,是优质的http实现
- HttpServerCodec是一个编码处理器,用于管道时间监听.
- FullHttpResponse对象是设置http协议,header请求头属性
- favicon.ico当浏览器进行发送请求的时候,会去根目录进行查找
- Netty没有提供路由,需要开发者自己实现,它也没有完善的Http支持,也有开发设计者决定


2、Netty的Channel通道
- Channel通道类似是拦截器(ChannelPipeline)针对客户端的请求进行处理
ChannelPipeline关系图
3、Netty的EventLoopGroup摘要
- EventLoopGroup其实是使用了死循环,对连接不断接收数据
- EventLoopGroup是一个线程组,在使用时是推荐两个EventLoopGroup,而且group方法,第一个参数是接收请求,不做任何业务处理(Reactor模型的mainReactor)。第二个参数是对要实现的对象处理,(相当于Reactor模型的subReactor)

4、Netty的ChannelInitializer摘要
- ChannelInitializer 这个类表示,一旦被连接之后会注册,而且只有一个抽象方法

5、Netty重要方法
- 使用write方法数据会放在缓冲区,不会返回客户端响应请求,所以推荐使用writeAndFlush方法
- channelRead0在Netty5.0发生了改变,重命名了messageReceived方法


6、Netty设计理念
-
Netty设计理思想对大多数线程控制
多数线程
7、NioServerSocketChannel
- NioServerSocketChannel对象内部绑定了Java NIO创建的ServerSocketChannel对象;
- Netty中,AbstractChannel有一个unsafe对象,此对象封装了Java NIO底层channel的操作细节;
-
Netty中,每个channel都有一个pipeline对象,此对象就是一个双向链表;
NioServerSocketChannel

public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
@Override
protected AbstractNioUnsafe newUnsafe() {
return new NioMessageUnsafe();
}
}
8、代码实现
- TestServer代码
public class TestServer {
public static void main(String[] args) throws Exception {
//创建bossGroup
EventLoopGroup bossGroup = new NioEventLoopGroup();
//创建workerGroup
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//创建ServerBootstrap
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new TestServerInitializer());
//绑定端口
ChannelFuture channelFuture = serverBootstrap.bind(8080).sync();
//同步
channelFuture.channel().closeFuture().sync();
} finally {
//优雅关闭
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
- TestHttpServerHandler
public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
System.out.println(msg.getClass());
System.out.println(ctx.channel().remoteAddress());
if (msg instanceof HttpRequest) {
HttpRequest httpRequest = (HttpRequest)msg;
System.out.println("请求方法名:" + httpRequest.method().name());
URI uri = new URI(httpRequest.uri());
if("/favicon.ico".equals(uri.getPath())) {
System.out.println("请求favicon.ico");
return;
}
ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8);
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
ctx.writeAndFlush(response);
ctx.channel().close();
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel active");
super.channelActive(ctx);
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel registered");
super.channelRegistered(ctx);
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
System.out.println("handler added");
super.handlerAdded(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel inactive");
super.channelInactive(ctx);
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel unregistered");
super.channelUnregistered(ctx);
}
}
- TestServerInitializer
public class TestServerInitializer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("httpServerCodec", new HttpServerCodec());
pipeline.addLast("testHttpServerHandler", new TestHttpServerHandler());
}
}
9、其他(常用命令)
- curl是一个完整网络请求命令
- lsof -i : 8080 是mac电脑的命令,表示list open file的意思