Netty 시작하기 (2)

고성능 메모리 모델과 유연한 파이프라인

김대현
@hatemogi

src/nettystartup/h1/discard/DiscardServerHandler.java


class DiscardServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        try {
            // discard
        } finally {
            buf.release();
        }
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
						

src/nettystartup/h1/echo/EchoServerHandler.java


class EchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ctx.write(msg);
    }
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
						

http://localhost:8020/

src/nettystartup/h2/http/HttpStaticServer.java


public class HttpStaticServer {
    static String index = System.getProperty("user.dir") + "/res/h2/index.html";

    public static void main(String[] args) throws Exception {
        NettyStartupUtil.runServer(8020, new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) {
                ChannelPipeline p = ch.pipeline();
                p.addLast(new HttpServerCodec());
                p.addLast(new HttpObjectAggregator(65536));
                p.addLast(new HttpStaticFileHandler("/", index));
                // TODO: [실습2-2] HttpNotFoundHandler를 써서 404응답을 처리합니다.
            }
        });
    }
}
						

src/nettystartup/h2/http/HttpStaticFileHandler.java


public class HttpStaticFileHandler extends SimpleChannelInboundHandler<HttpRequest> {
    private String path;
    private String filename;

    public HttpStaticFileHandler(String path, String filename) {
        super(false); // set auto-release to false
        this.path = path;
        this.filename = filename;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
        // TODO: [실습2-1] sendStaticFile메소드를 써서 구현합니다. "/" 요청이 아닌 경우에는 어떻게 할까요?
    }

    private void sendStaticFile(ChannelHandlerContext ctx, HttpRequest req) throws IOException {
    	...
    }
}

						

src/nettystartup/h2/http/HttpNotFoundHandler.java


public class HttpNotFoundHandler extends SimpleChannelInboundHandler<HttpRequest> {
    @Override
    protected void channelRead0(C..H..Context ctx, HttpRequest req) throws E.. {
        ByteBuf buf = Unpooled.copiedBuffer("Not Found", CharsetUtil.UTF_8);
        FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND, buf);
        res.headers().set(CONTENT_TYPE, "text/plain; charset=utf-8");
        if (HttpHeaders.isKeepAlive(req)) {
            res.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
        }
        res.headers().set(CONTENT_LENGTH, buf.readableBytes());
        ctx.writeAndFlush(res).addListener((ChannelFuture f) -> {
            if (!HttpHeaders.isKeepAlive(req)) {
                f.channel().close();
            }
        });
    }
}