如何使用netty通过HTTP流式传输响应 [英] how to stream a response over HTTP with netty

查看:863
本文介绍了如何使用netty通过HTTP流式传输响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Netty 3.6.6,我想将较大的响应发送回给呼叫者.我无法将响应主体复制到ChannelBuffer中,因为在某些情况下,响应主体会很大.

I'm using Netty 3.6.6 and I'd like to send a large response back to the caller. I can't copy the response body into a ChannelBuffer as in some cases it will be very large.

我要将服务器从CXF迁移到Netty,以前,我只能使用CXF提供的OutputStream写入数据.

I'm migrating a server from CXF to Netty, previously, I could just use the OutputStream provided by CXF to write the data.

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

I originally tried to just send the response without content, and then continued to write data to the Channel in a series of 8k buffers. This failed as the client seemed to get the original response and see no data and complain. I tried setting the response as chunked, but this didnt seem to make a difference, nor did setting the chunked header, the client always saw an empty stream.

我看到了3.6.6的文件服务器示例,该示例与我要执行的操作类似,只是数据不会是文件.我看到了ChunkedStream& NioStream,看起来很接近我的需要,除了它们使用InputStream/ReadableByteChannel,而我拥有一个OutputStream之外;我可以尝试使用PipedInput& OutputStreams,但这似乎会带来不幸的瓶颈.

I saw the file server example for 3.6.6, and that's similar to what I want to do, except the data will not be a file. I saw the ChunkedStream & NioStream, which seemed close to what I need, except they take InputStream/ReadableByteChannel whereas I have an OutputStream; I could try using the PipedInput & OutputStreams, but that seems like it would introduce an unfortunate bottleneck.

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

I'm sure there's a way to stream a lot of data back to the client in response to a request, but I'm just not seeing how to do it unless I have a file.

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

I am also curious how you let the client know the response is complete if the connection is keep-alive, and you're streaming content, but don't know the content length. Seems like the client would wait forever for the connection to close in those cases.

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

Modifying the static file server example from 3.6.6 to remove the content-length header (just comment it out), specify that its a chunked response

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

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

and then using ChunkedNioStream to send the file after writing the response:

    // 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));

产生了不希望的行为,客户端获得了数百个字节,然后停止接收,基本上就是我在应用程序中看到的内容.正确的事情似乎只发生在content-length上,这在我的用例中是不可行的.

Yields the undesired behavior, the client gets a couple hundred bytes and then stop receiving, basically what I'm seeing in my application. The correct thing only seems to happen with a content-length, which is not feasible in my use case.

推荐答案

当您尝试将ChunkedNioStream写入ChunkedWriteHandler时,它只会生成一个流,其中包含ChunkedNioStream only .也就是说,它生成的是ChannelBuffer而不是HttpChunk.

When you attempt to write a ChunkedNioStream to ChunkedWriteHandler, it merely produces a stream which contains the content of the ChunkedNioStream only. That is, it produces ChannelBuffers rather than HttpChunks.

因为HttpMessageEncoder仅处理HttpMessageHttpChunk,所以ChunkedNioStream生成的ChannelBuffer被绕过了线路,没有前置HTTP块头,从而导致浏览器混乱.

Because HttpMessageEncoder handles only HttpMessage and HttpChunk, ChannelBuffer produced by ChunkedNioStream is bypassed to the wire, without HTTP chunk header prepended, causing your browser confused.

要解决此问题,您必须实现自己的ChunkedInput,该ChunkedInput生成HttpChunk而不是ChannelBuffer.但是,我必须同意这可能是一项艰巨的任务,因此您可能只想分叉HttpMessageEncoder,以便它也理解ChannelBuffer并将其像HttpChunk一样对待.请查看

To fix this problem, you have to implement your own ChunkedInput which produces HttpChunks instead of ChannelBuffers. However, I must agree that this might be a challenging task, so you might just want to fork HttpMessageEncoder so that it also understands ChannelBuffer and treats it just like HttpChunk. Please take a look at this part of HttpMessageEncoder for more information.

这篇关于如何使用netty通过HTTP流式传输响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆