Netty 执行流程分析与重要组件介绍

版权声明:如果觉得好的话,不防点个赞,那点你们认为不对或是需要补充,可以留言啊!本人原创,未经允许不得转载!! https://blog.csdn.net/qq_28289405/article/details/83089155

Netty的应用场景:

1、Netty可以作为RBC的通讯框架或是通讯的协议、通讯的库,实现了远程过程的调用,是基于socket的方式。这是在Netty开发里面很大的应用场景。

2、Netty可以作为长连接的服务器,就是基于websocket的长连接服务器,实现服务器与客户端之间的长连接的通信。

3、Netty还可以作为HTTP的服务器,类似于Tomcat 等servlet容器。但是当它充当HTTP服务器的时候,它的编程模型、获取请求的参数等并不是基于servlet规范的。可以通过浏览器去访问的。

一、用户向服务器发送请求,服务器返回一个helloworld的情景 (第三种应用场景)

1、channel :通道,相当于一个连接

2、channelHandler:通道的处理器,类似于处理器、拦截器这样的概念。请求过来之后,会一个一个的通过channelHandler来得到一个一个的处理,处理之后交给业务方法完成真正的处理,然后按照相反的顺序进行原路的返回

3、pipeline:管道。一个 pipeline是由多个channelHandler 构成的,构成管道的形式。请求过来的时候,会通过一个一个的处理器沿着管道不断的往前走

代码:本人创建的是gradel的项目

①、build.gradle

plugins {
    id 'java'
}

group 'com.cxm'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {

    compile group: 'io.netty', name: 'netty-all', version: '4.1.29.Final'

}

②、TestServer

package com.cxm.netty.firstexample;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @Date: 2018/10/16 15:35
 * @Description: 服务器启动代码
 */
public class TestServer {

    public static void main(String[] args) throws Exception{

        //定义两个事件循环组 (两个线程组)
        //NioEventLoopGroup()可以理解为死循环。不断的接受客户端发起的连接,连接进来之后对连接进行处理,紧接着循环继续运行
        // boosGroup --》线程组不断的从客户端那边接受连接,但是不对连接做任何的处理,直接传给worker
        // workerGroup --》线程组接收到boosGroup传过来的连接,真正的完成对连接的处理。例如获取连接的参数,进行实际的业务处理,把结果返回给客户端
        EventLoopGroup boosGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

       try{
           //ServerBootstrap 服务端启动,他实际上是一个比较方便的轻松的启动服务端的类
           ServerBootstrap serverBootstrap = new ServerBootstrap();
           // childHandler 子处理器 自己编写的处理器,请求到来时,有我们编写的处理器进行处理。
           serverBootstrap.group(boosGroup,workerGroup).channel(NioServerSocketChannel.class).childHandler(new TestServerInitializer());

           ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
           channelFuture.channel().closeFuture().sync();
       }finally {
           //优雅的关闭
           boosGroup.shutdownGracefully();
           workerGroup.shutdownGracefully();
       }
    }
}

③、TestServerInitializer

package com.cxm.netty.firstexample;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;

/**
 * @Date: 2018/10/16 16:00
 * @Description: 初始化器
 */
public class TestServerInitializer extends ChannelInitializer<SocketChannel> {

    //连接被创建之后会立刻执行 initChannel 回调方法
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        //pipeline 是 根据业务请求完成处理
        ChannelPipeline pipeline = ch.pipeline();

        //在最后添加 自定义的若干个处理器
        pipeline.addLast("httpServerCodec ",new HttpServerCodec());
        //添加自定义的处理器
        pipeline.addLast("testHttpServerHandler",new TestHttpServerHandler());
    }
}

④、TestHttpServerHandler

package com.cxm.netty.firstexample;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;

/**
 * @Date: 2018/10/16 16:08
 * @Description: 定义自己的处理器
 */
public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {

    //channelRead0 ---》 读取客户端发送过来真正的请求,并且向客户端返回响应
    //相当于 messageReceived
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {

        if (msg instanceof HttpRequest){

            //构造响应的字符串
            ByteBuf byteBuffer = Unpooled.copiedBuffer("Hello World" , CharsetUtil.UTF_8);

            //构造响应
            FullHttpResponse response =new DefaultFullHttpResponse(HttpVersion.HTTP_1_1 , HttpResponseStatus.OK,content);

            //设置 Response 头信息
            response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text_plain");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes());

            //返回给客户端的response对象
            ctx.writeAndFlush(response);
        }
    }
}

运行:

运行TestServer,  Linux打开  curl 'http://localhost:8899';就会出现 

执行流程:


1、首先会启动 Bootstrap 服务器,服务器里面会关联两个事件循环组(boosGroup,workerGroup)
2、在服务器启动的时候呢,会关联一个相应的处理器childHandler
3、在childHandler 里面定义的处理器 TestServerInitializer ,回调方法里面定义的若干个自定义的处理器,
也可以定义Netty本身内置的ChannelHandler,按照顺序往下走,
最终会走到我们自己提供的一个处理器TestHttpServerHandler,然后返回结果给客户端。

以上就是最基本的入门程序!! 

用网站来请求,他会请求你网站的图标,就如图的 favicon.ico

猜你喜欢

转载自blog.csdn.net/qq_28289405/article/details/83089155