Netty 实战:如何实现 HTTP 服务器?

例子说明一个HTTP服务器,它以纯文本格式发送回接收到的HTTP请求的内容 。

Netty 实战:如何实现 HTTP 服务器?

文章插图
 
源码HttpHelloWorldServer.JAVA这里指定了打印后台的日志信息 。
【Netty 实战:如何实现 HTTP 服务器?】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.HttpServerCodec;import io.netty.handler.codec.http.HttpServerExpectContinueHandler;import io.netty.handler.logging.LogLevel;import io.netty.handler.logging.LoggingHandler;public class HttpHelloWorldServer {    public static void main(String[] args) {        EventLoopGroup bossGroup = new NioEventLoopGroup();        EventLoopGroup workerGroup = new NioEventLoopGroup();        try {            ServerBootstrap serverBootstrap = new ServerBootstrap();            ChannelFuture channelFuture = serverBootstrap.group(bossGroup, workerGroup)                    .channel(NioServerSocketChannel.class)                    .option(ChannelOption.SO_BACKLOG, 1024)                    .handler(new LoggingHandler(LogLevel.INFO))                    .childHandler(new ChannelInitializer<SocketChannel>() {                        @Override                        protected void initChannel(SocketChannel ch) throws Exception {                            ch.pipeline().addLast(new HttpServerCodec(),                                    new HttpServerExpectContinueHandler(),                                    new HttpHelloWorldServerHandler());                        }                    })                    .bind(8889)                    .syncUninterruptibly();            channelFuture.channel().closeFuture().syncUninterruptibly();        } finally {            workerGroup.shutdownGracefully();            bossGroup.shutdownGracefully();        }    }}HttpHelloWorldServerHandler.javaimport io.netty.buffer.Unpooled;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelFutureListener;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.http.DefaultFullHttpResponse;import io.netty.handler.codec.http.FullHttpResponse;import io.netty.handler.codec.http.HttpHeaderNames;import io.netty.handler.codec.http.HttpHeaderValues;import io.netty.handler.codec.http.HttpObject;import io.netty.handler.codec.http.HttpRequest;import io.netty.handler.codec.http.HttpResponseStatus;import io.netty.handler.codec.http.HttpUtil;/** * <p> </p> * * <pre> Created: 2019/9/22 11:07 AM  </pre> * <pre> Project: netty-learn  </pre> * * @author 老马啸西风 */public class HttpHelloWorldServerHandler extends SimpleChannelInboundHandler<HttpObject> {    @Override    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {        // 刷新内容        ctx.flush();    }    @Override    protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {        if(msg instanceof HttpRequest) {            HttpRequest req = (HttpRequest) msg;            boolean keepAlive = HttpUtil.isKeepAlive(req);            FullHttpResponse response = new DefaultFullHttpResponse(req.protocolVersion(), HttpResponseStatus.OK,                    Unpooled.wrAppedBuffer("HelloWorld".getBytes()));            // 设置头信息            response.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN);            response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());            if(keepAlive) {                // 如果默认不是 keep alive                if(!req.protocolVersion().isKeepAliveDefault()) {                    response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);                } else {                    // Tell the client we're going to close the connection.                    response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);                }            }            // 写回响应            ChannelFuture f = ctx.write(response);            if(!keepAlive) {                f.addListener(ChannelFutureListener.CLOSE);            }        }    }}


推荐阅读