以前看过不少netty的文章,也照着网上代码试着敲过一些示例代码,但没咋系统深入的看过,买过netty权威指南也没咋看,现在又双叒叕打算重新开始学一下,从浅入深的开始。
第一篇搭建一个简单的http服务,熟悉一下netty使用的大致流程。
netty版本:
dependencies {
compile (
"io.netty:netty-all:4.1.10.Final"
)
}
启动类,主要是通过ServerBootstrap启动类来设置启动的各类参数:
public class TestServer {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new TestServerInitializer());
ChannelFuture channelFuture = serverBootstrap.bind(8899).sync();
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
ChannelInitializer实现类,主要作用是向pipeline中添加Handler:
public class TestServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("httpServerCodex", new HttpServerCodec());
pipeline.addLast("testHttpServerHandler", new TestHttpServerHandler());
}
}
Handler类,实现SimpleChannelInboundHandler方法,主要是处理收到的消息:
channelRead0这个名字取的有点莫名其妙,在源码中的注释中看到本来要在5.0的版本中改名为messageReceived,结果后来5.0版本被废弃了。。。
public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
if (msg instanceof HttpRequest) {
HttpRequest httpRequest = (HttpRequest)msg;
String name = httpRequest.method().name();
System.out.println("请求方法名:"+name);
String uri = httpRequest.uri();
System.out.println("请求uri:"+uri);
ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8);
DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
ctx.writeAndFlush(response);
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel active");
super.channelActive(ctx);
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel registered");
super.channelRegistered(ctx);
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
System.out.println("handler added");
super.handlerAdded(ctx);
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel inactive");
super.channelInactive(ctx);
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("channel unregistered");
super.channelUnregistered(ctx);
}
}
启动main方法,通过curl或者浏览器访问,即可看到服务器的返回: