内容过大时DefaultHttpResponse错误

时间:2012-12-19 19:15:42

标签: scala netty

我使用的是netty-3.5.11.Final.jar

我的引导程序如下:

val bootstrap = new ServerBootstrap(channelFactory)
bootstrap.getPipeline.addLast("httpDecoder", new HttpRequestDecoder())
bootstrap.getPipeline.addLast("aggregator", new HttpChunkAggregator(1024 * 1024 * 1024))
bootstrap.getPipeline.addLast("httpEncoder", new HttpResponseEncoder())
bootstrap.getPipeline.addLast("deflater", new HttpContentCompressor())
bootstrap.getPipeline.addLast("handler", new HttpRequestServerHandler())
bootstrap.setOption("child.tcpNoDelay", true)
bootstrap.setOption("child.keepAlive", true)

我的handlePost()看起来像是:

def handlePost(context: ChannelHandlerContext, request: HttpRequest) = {
  val response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)

  val body: Array[Byte] = ....

  response.setContent(ChannelBuffers.wrappedBuffer(body))
  context.getChannel.write(response)
  context.getChannel.close
}

如果我尝试发送长度为260000字节的主体,则它会正确发送。如果我发送一个更大的字节数组,那么我得到以下异常:

java.nio.channels.ClosedChannelException
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.cleanUpWriteBuffer(AbstractNioWorker.java:766)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.close(AbstractNioWorker.java:734)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:111)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:66)
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:54)
at org.jboss.netty.channel.Channels.close(Channels.java:820)
at org.jboss.netty.channel.AbstractChannel.close(AbstractChannel.java:197)
at com.lendingblocks.services.ServiceServer$HttpRequestServerHandler.messageReceived(ServiceServer.scala:65)
at org.jboss.netty.handler.codec.http.HttpContentEncoder.messageReceived(HttpContentEncoder.java:81)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
at org.jboss.netty.handler.codec.http.HttpChunkAggregator.messageReceived(HttpChunkAggregator.java:192)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:448)
at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:538)
at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:437)
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:84)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:471)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:332)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

为什么我会收到此错误以及如何解决?

1 个答案:

答案 0 :(得分:2)

netty的重点是异步操作。

写入调用不会阻止等待写入完成。写作和关闭是相互竞争谁将首先完成。您需要注册未来的监听器并在写完成后关闭通道。