3

我正在使用 Netty 3.6.6,我想向调用者发送一个很大的响应。我无法将响应正文复制到 ChannelBuffer 中,因为在某些情况下它会非常大。

我正在将服务器从 CXF 迁移到 Netty,以前,我可以只使用 CXF 提供的 OutputStream 来写入数据。

我最初尝试只发送没有内容的响应,然后继续在一系列 8k 缓冲区中向 Channel 写入数据。这失败了,因为客户似乎得到了原始响应并且看不到任何数据并抱怨。我尝试将响应设置为分块,但这似乎没有什么区别,也没有设置分块标头,客户端总是看到一个空流。

我看到了 3.6.6 的文件服务器示例,这与我想做的类似,除了数据不会是文件。我看到了 ChunkedStream 和 NioStream,这似乎与我需要的很接近,除了它们采用 InputStream/ReadableByteChannel 而我有一个 OutputStream;我可以尝试使用 PipedInput 和 OutputStreams,但这似乎会引入一个不幸的瓶颈。

我确信有一种方法可以将大量数据流回客户端以响应请求,但除非我有文件,否则我只是不知道该怎么做。

我也很好奇如果连接保持活动状态并且您正在流式传输内容但不知道内容长度,您如何让客户端知道响应已完成。在这些情况下,客户端似乎会永远等待连接关闭。

从 3.6.6 修改静态文件服务器示例以删除 content-length 标头(只需将其注释掉),指定其为分块响应

   response.setChunked(true);
   response.setHeader(Names.TRANSFER_ENCODING, Values.CHUNKED);

然后ChunkedNioStream在写入响应后使用发送文件:

    // Write the initial line and the header.
    ch.write(response);

    final ReadableByteChannel aIn = java.nio.channels.Channels.newChannel(new FileInputStream(file));
    ChannelFuture writeFuture = ch.write(new ChunkedNioStream(aIn));

产生不良行为,客户端获得几百个字节然后停止接收,基本上是我在应用程序中看到的。正确的事情似乎只发生在内容长度上,这在我的用例中是不可行的。

4

1 回答 1

5

当您尝试写入 aChunkedNioStreamChunkedWriteHandler,它只会生成一个包含ChunkedNioStream 唯一内容的流。也就是说,它产生ChannelBuffers 而不是HttpChunks。

因为HttpMessageEncoder只处理HttpMessageHttpChunkChannelBuffer产生的ChunkedNioStream被绕过到线路,没有预先设置 HTTP 块头,导致您的浏览器混淆。

要解决这个问题,你必须实现你自己的ChunkedInput,它产生HttpChunks 而不是ChannelBuffers。但是,我必须同意这可能是一项具有挑战性的任务,因此您可能只想分叉HttpMessageEncoder以便它也能ChannelBufferHttpChunk. 请查看此部分HttpMessageEncoder获取更多信息。

于 2013-10-17T12:42:29.870 回答