简体   繁体   English

Http服务器-Netty FileRegions是否可重用?

[英]Http Server - Are Netty FileRegions reusable?

I am currently working on an http server and some things are behaving kind of strange. 我目前正在使用http服务器,有些事情表现得有些奇怪。 I want to generate dynamic content and also just provide static files. 我想生成动态内容,还只提供静态文件。 Serving dynamic generated content works without problems. 提供动态生成的内容可以正常工作。 Since I want to profit from zero copy I use FileRegions to serve static files. 因为我想从零拷贝中获利,所以我使用FileRegions来提供静态文件。 My channel pipline contains the following handlers (in this order): 我的频道管道包含以下处理程序(按此顺序):

  1. HttpRequestDecoder HttpRequestDecoder
  2. HttpResponseEncoder HttpResponseEncoder
  3. HttpObjectAggregator HttpObjectAggregator
  4. ApiMapper ApiMapper

The ApiMapper is sharable and derived from the SimpleInboundHandler. ApiMapper是可共享的,并且从SimpleInboundHandler派生。 On creation the ApiMapper creates a FileRegion from a static file. 创建时,ApiMapper从静态文件创建FileRegion。 Now everytime the "/" uri is requested this happens: 现在,每次请求“ /” uri都会发生:

  1. A DefaultHttpReponse is written to the ChannelHandlerContext. DefaultHttpReponse写入ChannelHandlerContext。 The DefaultHttpReponse is not reused and contains headers for Content-Type and Content-Length DefaultHttpReponse不会重用,它包含Content-Type和Content-Length的标头
  2. The ReferenceCount of the FileRegion is increased using its retain method. FileRegion的ReferenceCount使用其keep方法增加。 Then writeAndFlush is called on the ChannelHandlerContext with the FileRegion as parameter. 然后,使用FileRegion作为参数在ChannelHandlerContext上调用writeAndFlush。 To the returned ChannelFuture a ChannelFutureListener is added which prints "DONE". 向返回的ChannelFuture中添加一个ChannelFutureListener,它显示“ DONE”。

The first response works as expected, the browser gets the full file and displays it correctly and "DONE" gets printed. 第一个响应将按预期工作,浏览器将获取完整文件并正确显示它,并打印“ DONE”。 But if the "/" uri is called again the browser doesn't show anything and just loads forever BUT "DONE" gets printed. 但是,如果再次调用“ /” uri,浏览器将不会显示任何内容,而是永远加载,但会打印“ DONE”。 Then after I restarted the server I used telnet to make the calls manually. 然后,在重新启动服务器后,我使用telnet手动进行呼叫。 The first response is correct, but then I noticed that the second call only returns a header, but no content. 第一个响应是正确的,但是随后我注意到第二个调用仅返回标头,但没有内容。 "DONE" still gets printed. “完成”仍然被打印。

So my question: Can the same FileRegion object be used multiple times? 所以我的问题是:同一个FileRegion对象可以多次使用吗? Am I doing anything other wrong? 我还有其他错吗?

No you can not write the same FileRegion multiple times this way as the transferred state is updated on the DefaultFileRegion object. 不,您不能多次写入同一个FileRegion,因为在DefaultFileRegion对象上更新了transferred状态。 You will need to create a new DefaultFileRegion instance for each write here. 您将需要为此处的每次写入创建一个新的DefaultFileRegion实例。

Also you need to ensure you send a LastHttpContent after your FileRegion as otherwise the state-machine in HttpResponseEncoder will not be in the correct state when you write the second HttpResponse . 另外,您还需要确保在LastHttpContent之后发送FileRegion ,否则在编写第二个HttpResponseHttpResponseEncoder的状态机将不会处于正确的状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM