在动手写Netty框架之前,我们先要了解http请求的组成,如下图:
从request的介绍我们可以看出来,一次http请求并不是通过一次对话完成的,他中间可能有很次的连接。通过上一章我们队netty的了解,每一次对话都会建立一个channel,并且一个ChannelInboundHandler一般是不会同时去处理多个Channel的。
如何在一个Channel里面处理一次完整的Http请求?这就要用到我们上图提到的FullHttpRequest,我们只需要在使用netty处理channel的时候,只处理消息是FullHttpRequest的Channel,这样我们就能在一个ChannelHandler中处理一个完整的Http请求了。
搭建一个Netty服务器,我们只需要两个类——一个是启动类,负责启动(BootStrap)和main方法,一个是ChannelHandler,负责具体的业务逻辑,我们先从启动类说起。
package com.dz.netty.http; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; 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.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; /** * Created by RoyDeng on 17/7/20. */ public class HttpServer { private final int port; public HttpServer(int port) { this.port = port; } public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println( "Usage: " + HttpServer.class.getSimpleName() + " <port>"); return; } int port = Integer.parseInt(args[0]); new HttpServer(port).start(); } public void start() throws Exception { ServerBootstrap b = new ServerBootstrap(); NioEventLoopGroup group = new NioEventLoopGroup(); b.group(group) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { System.out.println("initChannel ch:" + ch); ch.pipeline() .addLast("decoder", new HttpRequestDecoder()) // 1 .addLast("encoder", new HttpResponseEncoder()) // 2 .addLast("aggregator", new HttpObjectAggregator(512 * 1024)) // 3 .addLast("handler", new HttpHandler()); // 4 } }) .option(ChannelOption.SO_BACKLOG, 128) // determining the number of connections queued .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE); b.bind(port).sync(); } }
这个类同上一章中出现的Netty简易封装服务器代码类似,不一样的是这里使用了多个ChannelHandler,在这里一一介绍:
完成启动类之后,接下来就是我们的业务处理类HttpHandler了,先上代码:
转载:https://www.jianshu.com/p/ed0177a9b2e3