2015-06-29 2 views
0

Я реализовал сетевой сервер, работающий с клиентом, написанным в java. Проблема в том, что у меня есть проблема конфигурации конвейера, потому что у меня есть следующее сообщение: «достигнуто в хвосте конвейера. Проверьте конфигурацию вашего трубопровода». Я пробовал ответы на другие вопросы одного типа, но это не работает. У вас есть идея, как решить проблему? Вот мой инициализации моего сервера:Конфигурация сетей нетти

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(); 
    }*/ 
} 

ответ

1

Проблема заключается в эти обработчики в вашем трубопроводе:

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

Присутствие LineBasedFrameDecoder и StringDecoder означает, что входящий ByteBufs будет декодирован для строк, по одной строке в строке. Но HttpRequestDecoder ожидает, что ByteBufs не является строкой, поэтому входящие строки игнорируются, и после этого они достигают хвоста конвейера, где выводится предупреждающее сообщение.

Также StringEncoder не требуется, потому что HttpResponseEncoder уже излучает ByteBufs, которые готовы к передаче или encryped по SslHandler если они присутствуют.

+0

Спасибо за ваш ответ. Я удалил три строки –

+0

Но проблема всегда присутствует. –

+0

Вам также нужно что-то в хвосте вашего конвейера для обработки входящих HTTP-запросов. Это то, что должен делать ваш «NettyServerHandler»? Попробуйте переместить его, чтобы он был добавлен последним. –

1

Я нашел проблему. Это происходит из-за плохого использования метода 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());