Netty实现HTTP服务

简介: Netty实现HTTP服务

1 Netty模型

  • Netty抽象出两组线程池 BossGroup 专门负责接收客户端的连接, WorkerGroup 专门负责网络的读写
  • BossGroup 和 WorkerGroup 类型都是 NioEventLoopGroup
  • NioEventLoopGroup 相当于一个事件循环组, 这个组中含有多个事件循环 ,每一个事件循环是 NioEventLoop4) NioEventLoop 表示一个不断循环的执行处理任务的线程,每个 NioEventLoop 都有一个 selector , 用于监听绑定在其上的 socket的网络通讯
  • NioEventLoopGroup 可以有多个线程, 即可以含有多个 NioEventLoop
  • 每个 Boss NioEventLoop 循环执行的步骤有 3步
  • 轮询 accept 事件
  • 处理 accept 事件 , 与 client建立连接 , 生成 NioScocketChannel , 并将其注册到某个 worker NIOEventLoop 上的 selector
  • 处理任务队列的任务 , 即 runAllTasks
  • 每个 Worker NIOEventLoop 循环执行的步骤
  • 轮询 read, write 事件
  • 处理 i/o事件,即 read , write 事件,在对应 NioScocketChannel 处理
  • 处理任务队列的任务 , 即 runAllTasks
  • 每个Worker NIOEventLoop 处理业务时,会使用pipeline(管道), pipeline 中包含了 channel , 即通过pipeline可以获取到对应通道, 管道中维护了很多的处理器

2 Netty实现HTTP服务的基本流程

3 代码实现

依赖:

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.65.Final</version>
</dependency>

HttpServer.java

/**
 * @desc: Http服务端
 * @author: YanMingXin
 * @create: 2021/8/11-10:10
 **/
public class HttpServer extends ChannelInitializer<SocketChannel> {
    /**
     * 初始化管道,向管道加入处理器
     *
     * @param ch
     */
    @Override
    protected void initChannel(SocketChannel ch) {
        //得到管道
        ChannelPipeline pipeline = ch.pipeline();
        //HttpServerCodec是 netty 默认提供的处理http的编解码器 作用:codec =>[coder - decoder]
        pipeline.addLast("MyHttpServerCodec", new HttpServerCodec());
        //增加一个自定义的 handler
        pipeline.addLast("MyTestHttpServerHandler", new HttpServerHandler());
    }
}

HttpServerHandler.java

/**
 * @desc: Http请求处理器
 * 1. SimpleChannelInboundHandler 是 ChannelInboundHandlerAdapter
 * 2. HttpObject 客户端和服务器端相互通讯的数据被封装成 HttpObject
 * @author: YanMingXin
 * @create: 2021/8/11-10:11
 **/
public class HttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
    /**
     * channelRead0 读取客户端数据
     *
     * @param ctx
     * @param msg
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
        //判断 msg 是不是 HttpRequest请求
        if (msg instanceof HttpRequest) {
            System.out.println("当前管道:" + ctx.pipeline().hashCode() + " 当前HTTP处理器:" + this.hashCode());
            System.out.println("msg 类型:" + msg.getClass());
            System.out.println("客户端IP:" + ctx.channel().remoteAddress());
            //回复信息给浏览器
            ByteBuf content = Unpooled.copiedBuffer("Hello, I am Netty Http Server!", CharsetUtil.UTF_8);
            //构造一个 http的相应,即 HttpResponse
            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());
            //将构建好 response返回
            ctx.writeAndFlush(response);
        }
    }
}

TestServer.java

/**
 * @desc: 开启HTTP服务
 * @author: YanMingXin
 * @create: 2021/8/11-10:11
 **/
public class TestServer {
    public static void main(String[] args) throws Exception {
        //实例化BoosGroup,初始线程为1
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        //实例化NioEventGroup
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //实例化ServerBootstrap
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            //加入Selector
            serverBootstrap.group(bossGroup,
                    workerGroup).channel(NioServerSocketChannel.class).childHandler(new HttpServer());
            //获取Channel并绑定8888端口开启异步
            ChannelFuture channelFuture = serverBootstrap.bind(8888).sync();
            channelFuture.channel().closeFuture().sync();
        } finally {
            //关闭操作
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

测试:


相关文章
|
21天前
|
Web App开发 监控 Java
|
8月前
|
存储 JSON Go
Golang 语言 gRPC 服务怎么同时支持 gRPC 和 HTTP 客户端调用?
Golang 语言 gRPC 服务怎么同时支持 gRPC 和 HTTP 客户端调用?
91 0
|
21天前
|
前端开发 API UED
AngularJS的$http服务:深入解析与进行HTTP请求的技术实践
【4月更文挑战第28天】AngularJS的$http服务是核心组件,用于发起HTTP请求与服务器通信。$http服务简化了通信过程,通过深入理解和实践,能构建高效、可靠的前端应用。
|
21天前
|
移动开发 编解码 网络协议
用Java的BIO和NIO、Netty来实现HTTP服务器(三) 用Netty实现
用Java的BIO和NIO、Netty来实现HTTP服务器(三) 用Netty实现
|
21天前
|
编解码 网络协议 Java
用Java的BIO和NIO、Netty实现HTTP服务器(一) BIO与绪论
用Java的BIO和NIO、Netty实现HTTP服务器(一) BIO与绪论
|
21天前
|
XML 自然语言处理 前端开发
NLP自学习平台提供了API接口调用服务,这些接口可以通过HTTP GET请求进行调用
【2月更文挑战第7天】NLP自学习平台提供了API接口调用服务,这些接口可以通过HTTP GET请求进行调用
27 2
|
21天前
|
XML JSON 中间件
快速入门Gin框架搭建HTTP服务
快速入门Gin框架搭建HTTP服务
36 0
|
21天前
|
JSON Go 数据格式
一文搞懂Go快速搭建HTTP服务
一文搞懂Go快速搭建HTTP服务
25 0
|
21天前
|
网络协议 JavaScript Unix
TCP实现HTTP服务
TCP实现HTTP服务
34 0
|
21天前
|
网络协议 Linux
百度搜索:蓝易云【【http服务】使用命令来查看和停止端口教程。】
通过按照上述步骤使用命令来查看和停止端口,您可以轻松地管理正在运行的服务。请确保在停止端口上的服务时,选择正确的端口号,并谨慎操作以避免影响其他正常运行的服务。
34 0