2012-05-10 33 views
1

我有一個要求,能夠模擬具有分塊編碼的http響應。 Netty是能夠在高負載下模擬強大可擴展性的明顯選擇。然而,當一個響應頭由頭部從httpstaticfileserverhandler示例支持「Transfer-Encoding:chunked」示例

Transfer-Encoding: chunked

的請求的客戶端臨危響應頭,但從來沒有任何內容。

從Netty的例子,其中它表明響應HTTPS,我改變了它稍微

if (ch.getPipeline().get(SslHandler.class) != null || response.getHeader("Transfer-Encoding").equals("chunked")) 
{ 
    writeFuture = ch.write(new ChunkedFile(raf, 0, fileLength, 8192)); 
} else { 
    use FileRegion .... 
} 

if (!isKeepAlive(req)) { 
    outboundFuture.addListener(ChannelFutureListener.CLOSE); 
} 

因此,我預計chunkedFile通過ChunkedWriteHandler和響應處理沒有問題發送,但我可能是俯視着某物。

管道中的處理程序和順序相匹配的網狀例子

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 Handler()); 

Netty的堆棧跟蹤:

java.io.IOException: An existing connection was forcibly closed by the remote host 
    at sun.nio.ch.SocketDispatcher.write0(Native Method) 
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:33) 
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:72) 
    at sun.nio.ch.IOUtil.write(IOUtil.java:28) 
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:334) 
    at org.jboss.netty.channel.socket.nio.SocketSendBufferPool$PooledSendBuffer.transferTo(SocketSendBufferPool.java:241) 
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.write0(AbstractNioWorker.java:476) 
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:426) 
    at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:127) 
    at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:66) 
    at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:63) 
    at org.jboss.netty.channel.Channels.write(Channels.java:733) 
    at org.jboss.netty.handler.stream.ChunkedWriteHandler.flush(ChunkedWriteHandler.java:276) 
    at org.jboss.netty.handler.stream.ChunkedWriteHandler.handleDownstream(ChunkedWriteHandler.java:120) 
    at org.jboss.netty.channel.Channels.write(Channels.java:712) 
    at org.jboss.netty.channel.Channels.write(Channels.java:679) 
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245) 
    at nettyexample.Handler.messageReceived(Handler.java:93) 
    at org.jboss.netty.handler.stream.ChunkedWriteHandler.handleUpstream(ChunkedWriteHandler.java:141) 
    at org.jboss.netty.handler.codec.http.HttpChunkAggregator.messageReceived(HttpChunkAggregator.java:111) 
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) 
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.unfoldAndFireMessageReceived(ReplayingDecoder.java:600) 
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:584) 
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:445) 
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) 
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) 
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:94) 
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:372) 
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:246) 
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:38) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 
java.nio.channels.ClosedChannelException 
    at org.jboss.netty.handler.stream.ChunkedWriteHandler.discard(ChunkedWriteHandler.java:168) 
    at org.jboss.netty.handler.stream.ChunkedWriteHandler.flush(ChunkedWriteHandler.java:287) 
    at org.jboss.netty.handler.stream.ChunkedWriteHandler.handleDownstream(ChunkedWriteHandler.java:120) 
    at org.jboss.netty.channel.Channels.write(Channels.java:712) 
    at org.jboss.netty.channel.Channels.write(Channels.java:679) 
    at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:245) 
    at nettyexample.Handler.messageReceived(Handler.java:93) 
    at org.jboss.netty.handler.stream.ChunkedWriteHandler.handleUpstream(ChunkedWriteHandler.java:141) 
    at org.jboss.netty.handler.codec.http.HttpChunkAggregator.messageReceived(HttpChunkAggregator.java:111) 
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) 
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.unfoldAndFireMessageReceived(ReplayingDecoder.java:600) 
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:584) 
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:445) 
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) 
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) 
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:94) 
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:372) 
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:246) 
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:38) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 

回答

2

看一看這個線程:How to use ChunkedStream properly

要從響應報價...

當發送任意的分塊的數據,你必須首先發送一個新的DefaultHttpResponse(僅一次):隨時

HttpResponse res = new DefaultHttpResponse(); 
res.setChunked(true); 
res.setHeader(Names.TRANSFER_ENCODING, Values.CHUNKED); 
channel.write(res); 

那麼你一定要寫信給一個任意塊的通道,請致電:

HttpChunk chunk = new DefaultHttpChunk(ChannelBuffers.wrappedBuffer(str.getBytes(CharsetUtil.UTF_8))); 
channel.write(chunk); 

請確保您的HttpResponse對象上有setChunked

+0

很好的答案!只是一個側面說明'DefaultHttpResponse'需要兩個構造參數,所以'新的DefaultHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK)'將完成這項工作。 – lyomi

+0

請注意'.setHeader(...)'已被棄用一段時間;使用'.headers().set(...)'來代替通過'HttpHeaders'對象做同樣的事情 – bbarker