Netty实现Http服务器

本文介绍如何使用Netty框架搭建高性能的HTTP服务器。Netty是一个异步事件驱动的网络应用程序框架,适用于快速开发高并发的协议服务器。文章详细介绍了从环境搭建到具体请求处理的全过程,包括使用NioEventLoopGroup、ServerBootstrap、ChannelInitializer等核心组件。

                                                   Netty实现Http服务器

        Netty是一个异步事件驱动的网络应用程序框架用于快速开发和可维护的高性能协议服务器和客户端。Netty经过精心设计,具有丰富的协议,如FTP,SMTP,HTTP以及各种二进制和基于文本的传统协议。

       Java程序员在开发web应用的时候,截止2018年大多数公司采用的还是servlet规范的那一套来开发的,比如springmvc。虽然在2018年Java程序员们可以选择使用spring5中的webflux,但是这个转变没那么快。然而,基于servlet那一套的springmvc性能很差,可以使用netty来实现一个web框架。使用Netty实现一个简单的HTTP服务器。

1、搭建环境

implementation 'io.netty:netty-all:4.1.43.Final'

2、server

      netty的api设计非常好,具有通用性,几乎就是一个固定模式的感觉。server端的启动和客户端的启动代码十分相似。启动server的时候指定初始化器,在初始化器中,我们可以放一个一个的handler,而具体业务逻辑处理就是放在这一个个的handler中的。写好的server端代码如下:

public class TestServer {

    public static void main(String[] args){
        //循环组接收连接,不进行处理,转交给下面的线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        //循环组处理连接,获取参数,进行工作处理
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //服务端进行启动类
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            //使用NIO模式,初始化器等等
            serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new TestServerInitializer());
            //绑定端口
            ChannelFuture channelFuture = serverBootstrap.bind(9000).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

 注意:childHandler(new TestServerInitializer())  TestServerInitializer是自定义的Channel的处理器。

3、serverInitializer

        在这里可以指定我们的handler,handler是用来承载我们具体逻辑实现代码的地方,我们需要在ChannelInitializer中加入我们的具体的业务实现。

public class TestServerInitializer extends ChannelInitializer<SocketChannel> {

    //连接注册,创建成功,会被调用
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        //通道
        ChannelPipeline pipeline = ch.pipeline();
        //http的编解码
        pipeline.addLast("httpServerCodec",new HttpServerCodec());
        //http消息聚合器
        //Aggregator这个单次就是“聚合,聚集”的意思。http消息在传输的过程中可能是一片片的消息片端,所以当服务器接收到的是一片片的时候,就需要HttpObjectAggregator来把它们聚合起来。
        pipeline.addLast("httpAggregator",new HttpObjectAggregator(512*1024));
        //自定义处理器(具体实现逻辑)
        pipeline.addLast("testHttpServerHandler",new TestHttpServerHandler());

    }
}

4、具体请求处理

        读取channel里面的信息,进行处理之后,进行返回数据。

public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {

    private Log LOGGER = LogFactory.getLog(TestHttpServerHandler.class);

    //具体处理,读取客户端发过来的请求,把响应进行返回
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        LOGGER.info("channel read");
        if(msg instanceof HttpRequest){
            //响应内容,和编码处理
            ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8);
            //http协议版本,响应状态,和内容
            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 channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        LOGGER.info("channel unregistered");
        super.channelUnregistered(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        LOGGER.info("channel inactive");
        super.channelInactive(ctx);
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        LOGGER.info("channel registered");
        super.channelRegistered(ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        LOGGER.info("channel active");
        super.channelActive(ctx);
    }


    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        LOGGER.info("channel readComplete");
        super.channelReadComplete(ctx);
    }
}

5、启动测试

       测试路径:http://localhost:9000/

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值