netty入门使用

 

public class HttpServer {

    public void start(int port) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        int availProcessors = Runtime.getRuntime().availableProcessors();
        EventLoopGroup workerGroup = new NioEventLoopGroup(availProcessors*2);
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            //对http消息编解码
                            ch.pipeline().addLast(new HttpServerCodec());
                            //合并HttpMessage和HttpContent,构成FullHttpRequest或者FullHttpResponse
                            ch.pipeline().addLast(new HttpObjectAggregator(Integer.MAX_VALUE)); 
                            //支持大数据包发送,支持发送chunk块,支持HTTP协议的chunked编码
                            ch.pipeline().addLast(new ChunkedWriteHandler());
                            ch.pipeline().addLast(new UserHandler());
                        }
                    }).option(ChannelOption.SO_BACKLOG, 1024) //存放请求的缓冲队列的大小
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childOption(ChannelOption.SO_SNDBUF,1024*1024*32)
                    .childOption(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK,1024*1024*32)
                    .childOption(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK,1024*1024*24);

            ChannelFuture f = b.bind(port).sync();

            f.channel().closeFuture().sync();

        }catch (InterruptedException e){
            e.printStackTrace();
        }
        finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) throws Exception {
        HttpServer server = new HttpServer();
        server.start(9999);
    }
}

//FullHttpRequest是由于pipeline使用了HttpObjectAggregator
public class UserHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
        //--------------------------获取请求ip-----------------------------------------
        String clientIP = request.headers().get("X-Forwarded-For");
        if (clientIP == null) {
            InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
            clientIP = insocket.getAddress().getHostAddress();
        }
        
        //------------解析get请求参数:http://ip:port/path?key1=value1&key2=value2------
        QueryStringDecoder decoder = new QueryStringDecoder(request.getUri());
        String path = decoder.path();
        Map<String, List<String>> params = decoder.parameters();
        
        //---------------------------解析post请求参数-----------------------------------
        String contentType = request.headers().get("Content-Type");
        if(contentType.equals("application/json")){
            String jsonStr = request.content().toString(Charsets.toCharset(CharEncoding.UTF_8));
            Map params = JSON.parseObject(jsonStr,Map.class);
            for(Object key : params.keySet()){
                System.out.println(key + " " + params.get(key));
            }
        }else if(contentType.equals("application/x-www-form-urlencoded")){
            String content = request.content().toString(Charsets.toCharset(CharEncoding.UTF_8));
            QueryStringDecoder queryStringDecoder = new QueryStringDecoder(content,false);
            Map<String, List<String>> params = queryStringDecoder.parameters();
            for(Map.Entry<String,List<String>> entry : params.entrySet()){
                System.out.println(entry.getKey() + ":" + entry.getValue().get(0));
            }
        }else if(contentType.startsWith("multipart/form-data")){
            HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE), request, Charsets.toCharset(CharEncoding.UTF_8));

            List<InterfaceHttpData> datas = decoder.getBodyHttpDatas();
            System.out.println("enter 1");
            for(InterfaceHttpData data : datas){
                System.out.println("enter 2");
                System.out.println(data.getHttpDataType());
                if(data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
                    System.out.println("enter 3");
                    FileUpload fileUpload = (FileUpload) data;
                    System.out.println(fileUpload.content().toString(Charsets.toCharset(CharEncoding.UTF_8)));
                }
            }
        }
        
        //------------------------响应请求--------------------------------------------
        Map<String, Object> res = new HashMap<>();
        res.put("message", "done success");
        res.put("code", 0);
        String resJsonStr = JSON.toJSONString(res);
        ByteBuf content = copiedBuffer(resJsonStr, CharsetUtil.UTF_8);
        FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status,content);
        HttpHeaders.setContentLength(response,content.readableBytes());
        response.headers().set(CONTENT_TYPE,APPLICATION_JSON);
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
        
        //------------------------响应请求,http chunked编码---------------------------
        HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        HttpHeaders.setTransferEncodingChunked(response);   //指定chunked编码
        if (HttpHeaders.isKeepAlive(request)) {
            response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
        }
        ctx.write(response);
        //cbInputStream是一个InputStream
        ctx.write(new HttpChunkedInput(new ChunkedStream(cbInputStream, 1024 * 32)), ctx.newProgressivePromise());
        ChannelFuture lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
        if (!HttpHeaders.isKeepAlive(request)) {
            lastContentFuture.addListener(ChannelFutureListener.CLOSE);
        }       
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值