0

我正在尝试在 netty 中实现某种 http 代理,为此我需要一个一个地从磁盘发送几个文件。为此,我实现了简单的 ChannelFutureListener,它在“operationComplete”上发送下一个文件:

public class FrontendArchive implements ChannelFutureListener {
    private final ChannelHandlerContext ctx;
    private final Archive archive;

    public void sendNext() {
        Entity entity = archive.nextEntity();
        if (entity == null) {
            //No more data
            // Write the end marker
            ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT).addListener(ChannelFutureListener.CLOSE);
            return;
        }

        try {
            ctx.writeAndFlush(entity.getData()).addListener(this);
        } catch (IOException e) {
            //We have nothing to do atm, but break the connection.
            log.error("Exception: {}", e.getMessage(), e);
            ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT).addListener(ChannelFutureListener.CLOSE);
        }
    }


    @Override
    public void operationComplete(ChannelProgressiveFuture channelProgressiveFuture) throws Exception {
        this.sendNext();
    }
}

getData 非常简单:

public Object getData() throws IOException {
try(RandomAccessFile raf = new RandomAccessFile(new File(this.getLocation()), "r")) {
    long fileLength = raf.length();

    // Write the content.
    return new ChunkedFile(raf, 0, fileLength, SEND_BUFFER);
}
}

问题是,由于某种原因,侦听器的“操作完成”仅对前几个文件调用,而另一端从未收到实际数据。我做错了什么?

4

1 回答 1

0

好吧,netty 很聪明,可以自动对写入请求进行排队。因此,上面的代码可以简化为:

    // Start sending data.
    Entity entity = archive.get().nextEntity();
    try {
        while (entity != null) {
            ctx.write(entity.getData());
            entity = archive.get().nextEntity();
        }
    } catch (IOException e) {
        log.error("Exception during zip serving: {}", e.getMessage(), e);
    } finally {
        ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT).addListener(ChannelFutureListener.CLOSE);
    }

您不必等待传输完成并允许一次将所有传输排队。

于 2014-05-02T09:06:55.183 回答