Сервер Netty не отправляет все данные при закрытии канала

#netty

#netty

Вопрос:

Я новичок в netty и не понимаю, почему ответ сервера частично теряется на моем сервере. Я уже прочитал несколько опубликованных вопросов, но я не могу решить проблему.

Я использую версию netty 4.0.46. Сервер должен закрыть соединение, как только он отправит все данные ответа. Я использую SimpleChannelInboundHandler и пытаюсь закрыть канал с помощью ChannelFutureListener после отправки ответа.

 public class AlbaranXMLServerHandler extends SimpleChannelInboundHandler<String> {
...
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String host = ((InetSocketAddress)ctx.channel().remoteAddress()).getAddress().getHostAddress();
        int port = ((InetSocketAddress)ctx.channel().remoteAddress()).getPort();
        logger.debug(String.format("Nueva conexión. host:%s port:%d", host, port));
    }

@Override
public void channelRead0(ChannelHandlerContext ctx, String request)
        throws Exception {

    logger.info("Request received: "   request);
    .......

    logger.debug("XML Response: "   response);  

    ChannelFuture future = ctx.writeAndFlush(response);
    future.addListener(ChannelFutureListener.CLOSE);
    .......
}
  

Когда данных ответа (XML-строки) немного, проблемы нет, и клиент получает полный XML-файл. Но когда дело доходит до большого XML-файла, передача прерывается, по-видимому, когда прослушиватель закрывает канал.

В журнале отладки сервера всегда отображается полный XML Ok.

Есть ли что-то, чего я не понимаю в том, как netty записывает / закрывает канал?

Инициализатор канала

 public class AlbaranXMLServerInitializer extends ChannelInitializer<SocketChannel> {
......
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();

        // Add the text line codec combination first,
        pipeline.addLast("framer", new FixedLengthFrameDecoder(AlbaranXMLServerHandler.TRAMA_PETICION_LONGITUD));
        // the encoder and decoder are static as these are sharable
        pipeline.addLast("decoder", DECODER);
        pipeline.addLast("encoder", ENCODER);

        // and then business logic.
        pipeline.addLast("handler", new AlbaranXMLServerHandler(rutaAlbaranes, autenticacionRFCService, albaranXMLRFCService, grupoSociedadesRFCService));
    }
}
  

Сервер

             @Service 
public class AlbaranXMLServer extends SocketServerBase {
    logger.info("Inicializando el servicio "   this.getClass().getSimpleName()   " ...");

            bossGroup = new NioEventLoopGroup();
            workerGroup = new NioEventLoopGroup();

            try {
                ServerBootstrap b = new ServerBootstrap();
                b.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .childHandler(this.getChannelInitializer());

                Channel channel = b.bind(port).sync().channel();
                logger.info("Finalizada la inicialización del servicio "   this.getClass().getSimpleName());

            } catch (Exception e) {
                logger.warn("Error al inicializar el servicio "   this.getClass().getSimpleName(), e);
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }