有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Netty4:channelRead0从未收到HttpObject消息

我已经使用netty创建了一个服务器,它接收HTTP get请求并回复客户机。我的服务器永远在运行。我可以在netty日志中看到收到的消息,但它从未到达channelRead0。下面是我的服务器代码:

HTTPServer:

public class HTTPServer {


    static final int PORT = Integer.parseInt(System.getProperty("port", "8080"));


    public static void main(String[] args) throws Exception {

        // Configure the server.
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        HTTPServerInitializer initializer = new HTTPServerInitializer();
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
        .channel(NioServerSocketChannel.class)
        .handler(new LoggingHandler(LogLevel.INFO))
        .childHandler(initializer);

        b.bind(PORT).syncUninterruptibly();
    }
}

HTTPServerHandler:

    @SuppressWarnings("deprecation")
    public class HTTPServerHandler extends SimpleChannelInboundHandler<HttpObject> {

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) {
            ctx.flush();
        }

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
            HttpResponseStatus status = HttpResponseStatus.BAD_REQUEST;
            if (msg instanceof HttpRequest) {
                HttpRequest request = (HttpRequest) msg;
                if (HttpMethod.GET.equals(request.getMethod())) {
                    if (request.getUri().equals("/ping")) {
                        status = OK;
                    }
                }
            }
            ctx.writeAndFlush(new DefaultFullHttpResponse(HTTP_1_1, status));
        }
}

HTTPServerInitializer:

public class HTTPServerInitializer extends ChannelInitializer<SocketChannel> {

@Override
    public void initChannel(SocketChannel ch) {
        ChannelPipeline p = ch.pipeline();
        p.addLast("log", new LoggingHandler(LogLevel.INFO));
        p.addLast(new HttpRequestDecoder());
        // Uncomment the following line if you don't want to handle HttpChunks.
        p.addLast(new HttpObjectAggregator(1048576));
        p.addLast(new HttpResponseEncoder());
        // Remove the following line if you don't want automatic content compression.
        //p.addLast(new HttpContentCompressor());
        p.addLast(new HTTPServerHandler());
    }

下面是我的客户端代码:
HTTPClient:

    public  class HTTPClient {

    public static void main(String[] args) throws Exception {
        String host = "127.0.0.1";
        int port = 8080;

        HTTPClientInitializer initializer = new HTTPClientInitializer();
        // Configure the client.
        EventLoopGroup group = new NioEventLoopGroup();


        Bootstrap b = new Bootstrap();
        b.group(group)
        .channel(NioSocketChannel.class)
        .handler(initializer);

        // Make the connection attempt.
         Channel ch = b.connect(host, port).sync().channel();

        // Prepare the HTTP request.
        HttpRequest request = new DefaultFullHttpRequest(
                HttpVersion.HTTP_1_1, HttpMethod.GET, "/ping");
        request.headers().set(HttpHeaderNames.HOST, host);

        // Send the HTTP request.
        ch.writeAndFlush(request);


    }
}

HTTPClientHandler:

public class HTTPClientHandler extends SimpleChannelInboundHandler<HttpObject> {


    @Override
    public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        if (msg instanceof HttpResponse) {
            String address = ctx.channel().remoteAddress().toString();
            System.out.println("Address: " + address);
        }
        else
        {
            System.out.println("invalid response");
        }

    }
}

HTTPClientInitializer:

public class HTTPClientInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        // Create a default pipeline implementation.
        ChannelPipeline p = ch.pipeline();

        p.addLast("log", new LoggingHandler(LogLevel.INFO));

        p.addLast("codec", new HttpClientCodec());

        // Remove the following line if you don't want automatic content decompression.
        //p.addLast("inflater", new HttpContentDecompressor());

        // Uncomment the following line if you don't want to handle HttpChunks.
        p.addLast("aggregator", new HttpObjectAggregator(1048576));

        p.addLast("handler", new HTTPClientHandler());
    }

}

因此,当我运行客户端和服务器时,下面是输出:
服务器窗口:

INFO: [id: 0x0c755e44] REGISTERED
Jul 13, 2017 6:45:20 PM io.netty.handler.logging.LoggingHandler bind
INFO: [id: 0x0c755e44] BIND: 0.0.0.0/0.0.0.0:8080
Jul 13, 2017 6:45:20 PM io.netty.handler.logging.LoggingHandler channelActive
INFO: [id: 0x0c755e44, L:/0:0:0:0:0:0:0:0:8080] ACTIVE
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler channelRead
INFO: [id: 0x0c755e44, L:/0:0:0:0:0:0:0:0:8080] READ: [id: 0x37432a61, L:/127.0.0.1:8080 - R:/127.0.0.1:56763]
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler channelReadComplete
INFO: [id: 0x0c755e44, L:/0:0:0:0:0:0:0:0:8080] READ COMPLETE
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler channelRegistered
INFO: [id: 0x37432a61, L:/127.0.0.1:8080 - R:/127.0.0.1:56763] REGISTERED
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler channelActive
INFO: [id: 0x37432a61, L:/127.0.0.1:8080 - R:/127.0.0.1:56763] ACTIVE
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler channelRead
INFO: [id: 0x37432a61, L:/127.0.0.1:8080 - R:/127.0.0.1:56763] READ: 39B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 47 45 54 20 2f 70 69 6e 67 20 48 54 54 50 2f 31 |GET /ping HTTP/1|
|00000010| 2e 31 0d 0a 68 6f 73 74 3a 20 31 32 37 2e 30 2e |.1..host: 127.0.|
|00000020| 30 2e 31 0d 0a 0d 0a                            |0.1....         |
+--------+-------------------------------------------------+----------------+
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler write
INFO: [id: 0x37432a61, L:/127.0.0.1:8080 - R:/127.0.0.1:56763] WRITE: 19B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d |HTTP/1.1 200 OK.|
|00000010| 0a 0d 0a                                        |...             |
+--------+-------------------------------------------------+----------------+
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler flush
INFO: [id: 0x37432a61, L:/127.0.0.1:8080 - R:/127.0.0.1:56763] FLUSH
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler channelReadComplete
INFO: [id: 0x37432a61, L:/127.0.0.1:8080 - R:/127.0.0.1:56763] READ COMPLETE
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler flush
INFO: [id: 0x37432a61, L:/127.0.0.1:8080 - R:/127.0.0.1:56763] FLUSH

客户端窗口:

INFO: [id: 0x91a94c8e] REGISTERED
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler connect
INFO: [id: 0x91a94c8e] CONNECT: /127.0.0.1:8080
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler channelActive
INFO: [id: 0x91a94c8e, L:/127.0.0.1:56763 - R:/127.0.0.1:8080] ACTIVE
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler write
INFO: [id: 0x91a94c8e, L:/127.0.0.1:56763 - R:/127.0.0.1:8080] WRITE: 39B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 47 45 54 20 2f 70 69 6e 67 20 48 54 54 50 2f 31 |GET /ping HTTP/1|
|00000010| 2e 31 0d 0a 68 6f 73 74 3a 20 31 32 37 2e 30 2e |.1..host: 127.0.|
|00000020| 30 2e 31 0d 0a 0d 0a                            |0.1....         |
+--------+-------------------------------------------------+----------------+
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler flush
INFO: [id: 0x91a94c8e, L:/127.0.0.1:56763 - R:/127.0.0.1:8080] FLUSH
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler channelRead
INFO: [id: 0x91a94c8e, L:/127.0.0.1:56763 - R:/127.0.0.1:8080] READ: 19B
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d |HTTP/1.1 200 OK.|
|00000010| 0a 0d 0a                                        |...             |
+--------+-------------------------------------------------+----------------+
Jul 13, 2017 6:45:25 PM io.netty.handler.logging.LoggingHandler channelReadComplete
INFO: [id: 0x91a94c8e, L:/127.0.0.1:56763 - R:/127.0.0.1:8080] READ COMPLETE

正如您所看到的,客户端接收到响应,但从未到达channelRead0方法。我在这个问题上花了很多时间。有人能帮忙吗


共 (1) 个答案

  1. # 1 楼答案

    在Netty中,服务器负责处理此问题。添加以下行:

     future.addListener(ChannelFutureListener.CLOSE);  
    

    protected void channelRead0(ChannelHandlerContext ctx, HttpObject httpObject)解决了我的问题