Netty搭建http服务端
最近一直在看netty的相关资料。现在模拟一个简单的http服务端程序:
package com.xueyou.demo.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
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.HttpContentCompressor;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpServer {
static final Logger LOG = LoggerFactory.getLogger(HttpServer.class);
public static int MAX_CHUNK_SIZE = 1024 * 1024 * 30;
public void bind(int port) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline()
.addLast("http-decoder", new HttpRequestDecoder())
.addLast("http-chunk-aggregator",
new HttpObjectAggregator(HttpServer.MAX_CHUNK_SIZE))
.addLast("http-encoder", new HttpResponseEncoder())
.addLast("compressor", new HttpContentCompressor())
.addLast("handler", new NettyHttpServerHandler());
}
});
ChannelFuture f = b.bind(port).sync();
LOG.info(">>>>>>netty start port:{}<<<<<<", port);
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) {
int port = 45678;
try {
new HttpServer().bind(port);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
package com.xueyou.demo.server;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.profiler.Profiler;
public class NettyHttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
static final Logger LOG = LoggerFactory.getLogger(NettyHttpServerHandler.class);
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) throws Exception {
Profiler profiler = new Profiler("Timing profiler");
profiler.start("handle request");
LOG.info(fullHttpRequest.getUri());
LOG.info(fullHttpRequest.getMethod().toString());
profiler.start("handle response");
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
response.headers().set("content-Type", "text/html;charset=UTF-8");
StringBuilder sb = new StringBuilder();
sb.append("test");
ByteBuf responseBuf = Unpooled.copiedBuffer(sb, CharsetUtil.UTF_8);
response.content().writeBytes(responseBuf);
responseBuf.release();
profiler.start("write response");
channelHandlerContext.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
profiler.stop();
int spentMs = (int) profiler.elapsedTime() / 1000000;
LOG.warn(profiler.toString());
LOG.warn("Total Time is {}ms", spentMs);
}
}
运行后能够使用浏览器或者请求工具进行测试服务端。能够正常返回“test”。
需要注意的是,这里仅仅是一个例子,不能够作为实际的生产环境的服务端,很多问题,比如多线程,文件上传,静态资源,字符转码,获取参数,跨域等等都没有解决。这些都是一些基础的功能。这里不做研究。因为研究的主要目的是为了学习netty,后续我会继续跟进,更新netty学习的进度。
还没有评论,来说两句吧...