Java tutorial
/* * Copyright (C) 2014-present The Netty5-2015 Authors * * https://github.com/sdcuike * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.doctor.netty5.example.http.helloworld; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.SimpleChannelInboundHandler; 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.DefaultFullHttpResponse; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderUtil; import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.util.concurrent.Future; import java.nio.charset.StandardCharsets; /** * ?http??http://localhost:8989/ * * @author doctor * * @time 2015715 */ public class HelloWorldServer { private final int port; public HelloWorldServer() { this(8989); } public HelloWorldServer(int port) { this.port = port; } /** * * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { new HelloWorldServer().start(); } public void start() throws InterruptedException { ServerBootstrap bootstrap = new ServerBootstrap(); NioEventLoopGroup bossGroup = new NioEventLoopGroup(1); NioEventLoopGroup workerGroup = new NioEventLoopGroup(); try { bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).localAddress(port) .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()); ch.pipeline().addLast(new HelloWorldServerHandler()); } }); ChannelFuture channelFuture = bootstrap.bind().sync(); System.out.println(HelloWorldServer.class.getName() + " started and listen on port:" + channelFuture.channel().localAddress()); channelFuture.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } private static class HelloWorldServerHandler extends SimpleChannelInboundHandler<HttpRequest> { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close().addListener(HelloWorldServerHandler::closeOperationComplete); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override protected void messageReceived(ChannelHandlerContext ctx, HttpRequest msg) throws Exception { if (HttpHeaderUtil.is100ContinueExpected(msg)) { ctx.write(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE)); } boolean keepAlive = HttpHeaderUtil.isKeepAlive(msg); DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.copiedBuffer("Hello world", StandardCharsets.UTF_8)); response.headers().set(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.TEXT_PLAIN); response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes()); if (!keepAlive) { ctx.write(response).addListener(ChannelFutureListener.CLOSE); } else { response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); ctx.write(response); } } public static void closeOperationComplete(Future<? super Void> f) throws Exception { ChannelFuture channelFuture = (ChannelFuture) f; if (channelFuture.isSuccess()) { System.out.println(channelFuture.channel().remoteAddress() + "?"); } else { System.err.println(channelFuture.channel().remoteAddress() + ""); } } } }