package cn.org.hentai.jtt1078.app; import cn.org.hentai.jtt1078.http.GeneralResponseWriter; import cn.org.hentai.jtt1078.http.NettyHttpServerHandler; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; 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.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.net.InetAddress; @Slf4j @Component public class HttpServer { private ServerBootstrap serverBootstrap; private EventLoopGroup bossGroup; private EventLoopGroup workerGroup; @Value("${jt1078.http.port}") private int port; public void start() throws Exception { bossGroup = new NioEventLoopGroup(1); // acceptor thread workerGroup = new NioEventLoopGroup(Runtime.getRuntime().availableProcessors()); serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override public void initChannel(SocketChannel ch) { ch.pipeline().addLast( new GeneralResponseWriter(), new HttpResponseEncoder(), new HttpRequestDecoder(), new HttpObjectAggregator(1024 * 64), new NettyHttpServerHandler() ); } }) .option(ChannelOption.SO_BACKLOG, 1024) .childOption(ChannelOption.SO_KEEPALIVE, true); ChannelFuture f = serverBootstrap.bind(InetAddress.getByName("0.0.0.0"), port).sync(); log.info("🌐 Web Server started on port {}", port); } @PreDestroy public void shutdown() { try { if (workerGroup != null) workerGroup.shutdownGracefully(); if (bossGroup != null) bossGroup.shutdownGracefully(); log.info("HTTP Server shutdown gracefully"); } catch (Exception e) { e.printStackTrace(); } } }