Netty搭建http服务端

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wild46cat/article/details/82320667

最近一直在看netty的相关资料。现在模拟一个简单的http服务端程序:

package com.xueyou.demo.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpContentCompressor;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpServer {
    static final Logger LOG = LoggerFactory.getLogger(HttpServer.class);
    public static int MAX_CHUNK_SIZE = 1024 * 1024 * 30;

    public void bind(int port) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            socketChannel.pipeline()
                                    .addLast("http-decoder", new HttpRequestDecoder())
                                    .addLast("http-chunk-aggregator",
                                            new HttpObjectAggregator(HttpServer.MAX_CHUNK_SIZE))
                                    .addLast("http-encoder", new HttpResponseEncoder())
                                    .addLast("compressor", new HttpContentCompressor())
                                    .addLast("handler", new NettyHttpServerHandler());
                        }
                    });

            ChannelFuture f = b.bind(port).sync();
            LOG.info(">>>>>>netty start port:{}<<<<<<", port);
            f.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        int port = 45678;
        try {
            new HttpServer().bind(port);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }
}
package com.xueyou.demo.server;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.profiler.Profiler;


public class NettyHttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    static final Logger LOG = LoggerFactory.getLogger(NettyHttpServerHandler.class);

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) throws Exception {
        Profiler profiler = new Profiler("Timing profiler");
        profiler.start("handle request");
        LOG.info(fullHttpRequest.getUri());
        LOG.info(fullHttpRequest.getMethod().toString());
        profiler.start("handle response");
        FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        response.headers().set("content-Type", "text/html;charset=UTF-8");
        StringBuilder sb = new StringBuilder();
        sb.append("test");
        ByteBuf responseBuf = Unpooled.copiedBuffer(sb, CharsetUtil.UTF_8);
        response.content().writeBytes(responseBuf);
        responseBuf.release();
        profiler.start("write response");
        channelHandlerContext.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
        profiler.stop();
        int spentMs = (int) profiler.elapsedTime() / 1000000;
        LOG.warn(profiler.toString());
        LOG.warn("Total Time is {}ms", spentMs);
    }
}

运行后能够使用浏览器或者请求工具进行测试服务端。能够正常返回“test”。

需要注意的是,这里仅仅是一个例子,不能够作为实际的生产环境的服务端,很多问题,比如多线程,文件上传,静态资源,字符转码,获取参数,跨域等等都没有解决。这些都是一些基础的功能。这里不做研究。因为研究的主要目的是为了学习netty,后续我会继续跟进,更新netty学习的进度。

猜你喜欢

转载自blog.csdn.net/wild46cat/article/details/82320667