网络管道配置



我已经实现了使用Java编写的客户端的netty服务器。问题是我有管道的配置问题,因为我有以下消息:"到达管道的尾部。请检查您的管道配置。我已经尝试了其他相同类型的问题的答案,但不起作用。您知道如何解决问题吗?这是我对服务器的初始化:

public class NettyServerInitializer extends ChannelInitializer<SocketChannel> {
    private final SslContext sslCtx;
    public NettyServerInitializer(SslContext sslCtx) {
        this.sslCtx = sslCtx;
    }
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline p = ch.pipeline();
        if (sslCtx != null) {
            p.addLast(sslCtx.newHandler(ch.alloc()));
        }
        p.addLast(
                new StringEncoder(CharsetUtil.UTF_8),
                new LineBasedFrameDecoder(8192),
                new StringDecoder(CharsetUtil.UTF_8),
                new ChunkedWriteHandler(),
                new NettyServerHandler());
        p.addLast(new HttpRequestDecoder());
        p.addLast(new HttpResponseEncoder());
        // Remove the following line if you don't want automatic content compression.
        p.addLast(new HttpContentCompressor());
        p.addLast( "http-aggregator", new HttpObjectAggregator( 1024 ) );
    }
}

和我的服务器代码:

public static void main(String... args) {
    try {
        new NettyServer().start();
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("API started on port {}", PORT);
        }
    } catch (final Exception e) {
        LOGGER.error("Unable to start API server", e);
    }
}


static final boolean SSL = System.getProperty("ssl") != null;
// Use the same default port with the telnet example so that we can use the telnet client example to access it.
static final int PORT = Integer.parseInt(System.getProperty("port", SSL? "8992" : "8080"));
public void start() throws Exception {
    // Configure SSL.
    final SslContext sslCtx;
    if (SSL) {
        SelfSignedCertificate ssc = new SelfSignedCertificate();
        sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
    } else {
        sslCtx = null;
    }
    // Configure the server.
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    //  try {
    ServerBootstrap b = new ServerBootstrap();
    b.group(bossGroup, workerGroup)
            .channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_BACKLOG, 100)
            .handler(new LoggingHandler(LogLevel.INFO))
            .childHandler(new NettyServerInitializer(sslCtx) {
            });
    // Start the server.
    ChannelFuture f = b.bind(PORT).sync();
    // Wait until the server socket is closed.
    //  f.channel().closeFuture().sync();
    /*   } finally {
    // Shut down all event loops to terminate all threads.
    bossGroup.shutdownGracefully();
    workerGroup.shutdownGracefully();
    }*/
}

问题是管道中的这些处理程序:

new StringEncoder(CharsetUtil.UTF_8),
new LineBasedFrameDecoder(8192),
new StringDecoder(CharsetUtil.UTF_8),

LineBasedFrameDecoderStringDecoder的存在意味着传入的ByteBufs将被解码为字符串,每行一个字符串。但是HttpRequestDecoder希望看到ByteBufs而不是字符串,因此传入的行将被忽略,然后它们到达打印出警告消息的管道尾部。

也不需要StringEncoder,因为HttpResponseEncoder已经发出ByteBufs,如果存在,可以由SslHandler传输或加密。

我发现了问题。这个来自方法的不良使用pipeline.addLast(...)。处理程序在队列中使用,队列必须由服务器的处理程序结束。

它不是:

p.addLast(
new ChunkedWriteHandler(),
new NettyServerHandler());
p.addLast(new HttpRequestDecoder());
p.addLast(new HttpResponseEncoder());
// Remove the following line if you don't want automatic content compression.
p.addLast(new HttpContentCompressor());

但:

p.addLast(new ChunkedWriteHandler())    
p.addLast(new HttpRequestDecoder());
p.addLast(new HttpResponseEncoder());
// Remove the following line if you don't want automatic content compression.
p.addLast(new HttpContentCompressor());
p.addLast(new NettyServerHandler());

最新更新