使用netty写一个简单的http server
package org.game.throne.proxy;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufProcessor;
import io.netty.buffer.Unpooled;
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 io.netty.util.CharsetUtil;
import java.util.ArrayList;
import java.util.List;
/**
* Created by lvtu on 2017/8/31.
*/
class MServerHandler extends ChannelInboundHandlerAdapter {
private StringBuilder body = new StringBuilder();
private List<Byte> bb = new ArrayList<>();
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if(msg instanceof DefaultHttpContent){
DefaultHttpContent httpContent = (DefaultHttpContent)msg;
ByteBuf content = httpContent.content();
content.forEachByte(new ByteBufProcessor(){
@Override
public boolean process(byte value) throws Exception {
bb.add(value);
return true;
}
});
body.append(content.toString());
}
if(msg instanceof DefaultLastHttpContent){
byte[] b = new byte[bb.size()];
for(int i=0;i<bb.size();i++){
b[i] = bb.get(i);
}
System.out.println(new String(b,"utf-8"));
ctx.flush();
}
if (msg instanceof HttpRequest) {
ByteBuf content = Unpooled.copiedBuffer("Hello World.", CharsetUtil.UTF_8);
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/plain");//必须加这个,否则浏览器不响应
response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, content.readableBytes());//必须加这个,否则浏览器不响应
response.headers().set(HttpHeaders.Names.CONNECTION, "keep-alive");
ctx.write(response);
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
}
public class MServer {
private int port;
public MServer(int port) {
this.port = port;
}
public void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // (3)
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new MServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128) // (5)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
// Bind and start to accept incoming connections.
ChannelFuture f = b.bind(port).sync(); // (7)
// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) {
try {
new MServer(8082).run();
}catch (Exception e){
e.printStackTrace();
}
}
}
问题点
1.netty通过文档或者看源码,都可以达到简单使用
2.最大的问题点是上面代码标注红色的地方,如果没有正确设定http response,浏览器是不会相应的,这是http协议规范的吗?