【问题标题】:Serving a file with Netty - response is truncated by one byte使用 Netty 提供文件 - 响应被截断一个字节
【发布时间】:2012-01-11 20:59:03
【问题描述】:

我通过 Netty 服务器(图像、html)提供来自 Android 资产的文件。 诸如 html 之类的文本文件保存为 .mp3 以禁用压缩(我需要一个 InputStream!)

我的管道如下所示:

    pipeline.addLast("decoder", new HttpRequestDecoder());
    pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
    pipeline.addLast("encoder", new HttpResponseEncoder());
    pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());

    pipeline.addLast("handler", new AssetsServerHandler(context));

我的处理程序是:

public class AssetsServerHandler extends SimpleChannelUpstreamHandler {

    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {

        // some checks

        final FileInputStream is;
        final AssetFileDescriptor afd;
        try {
            afd = assetManager.openFd(path);
            is = afd.createInputStream();   
        } catch(IOException exc) {
            sendError(ctx, NOT_FOUND);
            return;
        }

        final long fileLength = afd.getLength();

        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
        setContentLength(response, fileLength);

        final Channel ch = e.getChannel();
        final ChannelFuture future;
        ch.write(response);
        future = ch.write(new ChunkedStream(is));
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                future.getChannel().close();
            }
        });
        if (!isKeepAlive(request)) {
            future.addListener(ChannelFutureListener.CLOSE);
        }
    }
    // other stuff
}

使用该处理程序,我的响应至少被截断了一个字节。如果我将ChunkedStream 更改为ChunkedNioFile(因此使用is.getChannel() 而不是is 作为它的构造函数)- 一切正常。

请帮助我了解 ChunkedStream 出了什么问题。

【问题讨论】:

    标签: java android nio netty android-assets


    【解决方案1】:

    您的代码在我看来是正确的。 AssetFileDescriptor 返回的 FileInputStream 是否包含“所有字节”?您可以通过单元测试来检查这一点。如果它没有错误,那么它是netty中的错误。我大量使用 ChunkInputStream 并且从未遇到过这样的问题,但也许这真的取决于 InputStream 的性质。

    如果你能写一个测试用例并在 netty 的 github 上打开一个问题,那就太好了。

    【讨论】:

    • 我使用的FileInputStream 是在Android 核心的某处生成的。那我该如何进行单元测试呢?我认为这更多地取决于 Android 而不是 Netty。顺便说一句,Channel 我从这里得到了(同样的!!)FileInputStream 工作正常。
    • 我会编写一个将字节序列写入文件的单元测试。然后使用 AssetFileDescriptor 打开文件,获取 FileInputStream 并从中读取所有字节。然后检查每个字节是否等于您之前写入文件的字节。您应该针对不同的 FileInputStream.read(...) 方法进行测试...
    • 好主意,我会试试的。谢谢。
    • 告诉我你的发现
    猜你喜欢
    • 2014-09-11
    • 2014-08-13
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    • 2021-12-15
    • 2014-05-20
    相关资源
    最近更新 更多