我正在使用Netty 3.6.6,我想向调用者发送一个大的响应。我无法将响应主体复制到ChannelBuffer中,因为在某些情况下它会非常大。
我正在将服务器从CXF迁移到Netty,以前,我可以使用CXF提供的OutputStream来写入数据。
我最初尝试发送没有内容的响应,然后继续在一系列8k缓冲区中将数据写入Channel。这失败了,因为客户端似乎得到了原始响应并且看不到任何数据和抱怨。我尝试将响应设置为chunked,但这似乎没有什么区别,也没有设置chunked头,客户端总是看到一个空流。
我看到了3.6.6的文件服务器示例,这与我想要做的类似,除了数据不是文件。我看到了ChunkedStream& NioStream,它似乎接近我需要的,除了它们采用InputStream / ReadableByteChannel,而我有一个OutputStream;我可以尝试使用PipedInput& OutputStreams,但这似乎会带来一个不幸的瓶颈。
我确信有一种方法可以将大量数据流回客户端以响应请求,但我只是没有看到如何操作,除非我有一个文件。
我也很好奇如果连接保持活动状态,你是否让客户知道响应是否已完成,你是否正在流式传输内容,但不知道内容长度。似乎客户端会在这些情况下永远等待连接关闭。
修改3.6.6中的静态文件服务器示例以删除内容长度标题(只是将其注释掉),指定它是一个分块响应
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));
产生不良行为,客户端获得几百个字节然后停止接收,基本上就是我在应用程序中看到的内容。正确的事情似乎只发生在内容长度上,这在我的用例中是不可行的。
答案 0 :(得分:5)
当您尝试将ChunkedNioStream
写入ChunkedWriteHandler
时,它只会生成一个包含仅ChunkedNioStream
的内容的流。也就是说,它产生ChannelBuffer
而不是HttpChunk
s。
由于HttpMessageEncoder
仅处理HttpMessage
和HttpChunk
,ChannelBuffer
生成的ChunkedNioStream
被绕过线路,没有预先添加HTTP块标头,导致您的浏览器困惑。
要解决此问题,您必须实现自己的ChunkedInput
生成HttpChunk
而非ChannelBuffer
s。但是,我必须同意这可能是一项具有挑战性的任务,因此您可能只想分叉HttpMessageEncoder
,以便它也理解ChannelBuffer
并将其视为HttpChunk
。有关详细信息,请查看HttpMessageEncoder
的{{3}}。