import com.mdq.HttpServerTest.netty.handler.HttpServerInboundHandler;
import com.mdq.HttpServerTest.netty.handler.TestInBoundHandler1;
import com.mdq.HttpServerTest.netty.handler.TestOutBoundHandler1;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
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.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.codec.http.cors.CorsConfig;
import io.netty.handler.codec.http.cors.CorsConfigBuilder;
import io.netty.handler.codec.http.cors.CorsHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import io.netty.handler.stream.ChunkedWriteHandler;
public class NettyHttpServer {
private static Logger log = LoggerFactory.getLogger(NettyHttpServer.class);
static final boolean SSL = System.getProperty("ssl") != null;
static final int PORT = Integer.parseInt(System.getProperty("port", SSL ? "8443" : "8080"));
public void start(int port) throws Exception {
// Configure SSL.
final SslContext sslCtx;
if (SSL) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
} else {
sslCtx = null;
}
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
.childHandler(new HttpServerChannelInitializer(sslCtx))
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public class HttpServerChannelInitializer extends ChannelInitializer {
private final SslContext sslCtx;
public HttpServerChannelInitializer(SslContext sslCtx) {
this.sslCtx = sslCtx;
}
@Override
public void initChannel(SocketChannel ch) {
CorsConfig corsConfig = CorsConfigBuilder.forAnyOrigin().allowNullOrigin().allowCredentials().build();
ChannelPipeline pipeline = ch.pipeline();
if (sslCtx != null) {
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
}
pipeline.addLast("encoder", new HttpResponseEncoder());// server端发送httpResponse,需要进行编码
pipeline.addLast("outHandler1", new TestOutBoundHandler1("OutHandler1"));
pipeline.addLast("devoder", new HttpRequestDecoder()); // server端接收httpRequest,需要进行解码
// 聚合器,把多个消息转换为一个单一的FullHttpRequest或是FullHttpResponse
pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
pipeline.addLast(new ChunkedWriteHandler()); // 块写入处理器
pipeline.addLast(new CorsHandler(corsConfig));
pipeline.addLast("InHandler1", new TestInBoundHandler1("InHandler1"));
pipeline.addLast("InHandler2", new TestInBoundHandler1("InHandler2"));
pipeline.addLast(new HttpServerInboundHandler());
}
}
public static void main(String[] args) throws Exception {
NettyHttpServer server = new NettyHttpServer();
log.info("Http Server listening on 8844 ...");
server.start(8844);
}
}
【1】、NioEventLoopGroup 是用来处理I/O操作的线程池,Netty对 EventLoopGroup 接口针对不同的传输协议提供了不同的实现。在本例子中,需要实例化两个NioEventLoopGroup,通常第一个称为“boss”,用来accept客户端连接,另一个称为“worker”,处理客户端数据的读写操作。
【4】、通常会为新SocketChannel通过添加一些handler,来设置ChannelPipeline。ChannelInitializer 是一个特殊的handler,其中initChannel方法可以为SocketChannel 的pipeline添加指定handler。
服务端Http处理类Handler。Netty的FullHttpRequest、包含了读取uri,获取头部信息,解析Post/Get请求参数