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();
        }
    }
}

测试:


相关文章
|
4月前
|
JSON 中间件 Go
Go 网络编程:HTTP服务与客户端开发
Go 语言的 `net/http` 包功能强大,可快速构建高并发 HTTP 服务。本文从创建简单 HTTP 服务入手,逐步讲解请求与响应对象、URL 参数处理、自定义路由、JSON 接口、静态文件服务、中间件编写及 HTTPS 配置等内容。通过示例代码展示如何使用 `http.HandleFunc`、`http.ServeMux`、`http.Client` 等工具实现常见功能,帮助开发者掌握构建高效 Web 应用的核心技能。
273 61
|
4月前
|
应用服务中间件 网络安全 数据安全/隐私保护
网关服务器配置指南:实现自动DHCP地址分配、HTTP服务和SSH无密码登录。
哇哈哈,道具都准备好了,咱们的魔术秀就要开始了。现在,你的网关服务器已经魔法满满,自动分配IP,提供网页服务,SSH登录如入无人之境。而整个世界,只会知道效果,不会知道是你在幕后操控一切。这就是真正的数字世界魔法师,随手拈来,手到擒来。
239 14
|
6月前
|
中间件 Go
Golang | Gin:net/http与Gin启动web服务的简单比较
总的来说,`net/http`和 `Gin`都是优秀的库,它们各有优缺点。你应该根据你的需求和经验来选择最适合你的工具。希望这个比较可以帮助你做出决策。
252 35
|
Java Maven Windows
使用Java创建集成JACOB的HTTP服务
本文介绍了如何在Java中创建一个集成JACOB的HTTP服务,使Java应用能够调用Windows的COM组件。文章详细讲解了环境配置、动态加载JACOB DLL、创建HTTP服务器、实现IP白名单及处理HTTP请求的具体步骤,帮助读者实现Java应用与Windows系统的交互。作者拥有23年编程经验,文章来源于稀土掘金。著作权归作者所有,商业转载需授权。
282 2
使用Java创建集成JACOB的HTTP服务
|
5月前
|
前端开发 网络协议 应用服务中间件
Netty基础—7.Netty实现消息推送服务
本文详细介绍了如何使用Netty实现HTTP服务器、WebSocket以及基于WebSocket的消息推送系统。首先,通过解析HTTP请求和响应消息,展示了Netty在性能和可靠性上的优势,并提供了具体代码示例。接着,分析了HTTP协议的弊端及Ajax短轮询的不足,引出WebSocket全双工通信的优势,包括连接建立、数据处理逻辑与ping-pong探测等。最后,构建了一个完整的消息推送系统,涵盖PushServer、运营客户端与浏览器客户端的交互过程,实现了全连接推送和实时消息传递。
|
5月前
|
Java 开发者 索引
Netty基础—6.Netty实现RPC服务
本文详细介绍了RPC(远程过程调用)的相关概念及其实现细节,涵盖动态代理、Netty客户端和服务端处理、编码解码器以及超时功能的实现。
|
7月前
|
关系型数据库 MySQL PHP
源码编译安装LAMP(HTTP服务,MYSQL ,PHP,以及bbs论坛)
通过以上步骤,你可以成功地在一台Linux服务器上从源码编译并安装LAMP环境,并配置一个BBS论坛(Discuz!)。这些步骤涵盖了从安装依赖、下载源代码、配置编译到安装完成的所有细节。每个命令的解释确保了过程的透明度,使即使是非专业人士也能够理解整个流程。
164 18
|
Dubbo 前端开发 Java
Dubbo3 服务原生支持 http 访问,兼具高性能与易用性
本文展示了 Dubbo3 triple 协议是如何简化从协议规范与实现上简化开发测试、入口流量接入成本的,同时提供高性能通信、面向接口的易用性编码。
16984 110
使用Netty实现文件传输的HTTP服务器和客户端
本文通过详细的代码示例,展示了如何使用Netty框架实现一个文件传输的HTTP服务器和客户端,包括服务端的文件处理和客户端的文件请求与接收。
262 1
使用Netty实现文件传输的HTTP服务器和客户端
|
关系型数据库 MySQL 数据库
vertx 的http服务表单提交与mysql验证
本文介绍了如何使用Vert.x处理HTTP服务中的表单提交,并通过集成MySQL数据库进行验证,包括项目依赖配置、表单HTML代码和完整的Vert.x服务代码。
111 2