美文网首页Java 杂谈深入浅出Netty源码剖析Netty技术
【第2篇】Netty与Http执行流程与重要组件

【第2篇】Netty与Http执行流程与重要组件

作者: 爱学习的蹭蹭 | 来源:发表于2019-05-13 21:04 被阅读0次

1、Netty与Http的实现关键类摘要

  • Netty不是遵循Http的Servlet标准规范进行实现,是优质的http实现
  • HttpServerCodec是一个编码处理器,用于管道时间监听.
  • FullHttpResponse对象是设置http协议,header请求头属性
  • favicon.ico当浏览器进行发送请求的时候,会去根目录进行查找
  • Netty没有提供路由,需要开发者自己实现,它也没有完善的Http支持,也有开发设计者决定
FullHttpResponse关系图
HttpServerCodec关系图

2、Netty的Channel通道

  • Channel通道类似是拦截器(ChannelPipeline)针对客户端的请求进行处理
    ChannelPipeline关系图

3、Netty的EventLoopGroup摘要

  • EventLoopGroup其实是使用了死循环,对连接不断接收数据
  • EventLoopGroup是一个线程组,在使用时是推荐两个EventLoopGroup,而且group方法,第一个参数是接收请求,不做任何业务处理(Reactor模型的mainReactor)。第二个参数是对要实现的对象处理,(相当于Reactor模型的subReactor)
EventLoopGroup

4、Netty的ChannelInitializer摘要

  • ChannelInitializer 这个类表示,一旦被连接之后会注册,而且只有一个抽象方法
ChannelInitializer

5、Netty重要方法

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

6、Netty设计理念

  • Netty设计理思想对大多数线程控制


    多数线程

7、NioServerSocketChannel

  • NioServerSocketChannel对象内部绑定了Java NIO创建的ServerSocketChannel对象;
  • Netty中,AbstractChannel有一个unsafe对象,此对象封装了Java NIO底层channel的操作细节;
  • Netty中,每个channel都有一个pipeline对象,此对象就是一个双向链表;


    NioServerSocketChannel
unsafe
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的意思

相关文章

网友评论

    本文标题:【第2篇】Netty与Http执行流程与重要组件

    本文链接:https://www.haomeiwen.com/subject/mcfdaqtx.html