我正在用 netty 构建一个HTTP 代理,它支持 HTTP 流水线。因此,我HttpRequest
在单个通道上接收到多个对象并获得了匹配的HttpResponse
对象。写入的顺序HttpResponse
与我得到的相同HttpRequest
。如果 aHttpResponse
被写入,下一个将在HttpProxyHandler
收到writeComplete
事件时写入。
管道应该很方便:
final ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("encoder", new HttpResponseEncoder());
pipeline.addLast("writer", new HttpResponseWriteDelayHandler());
pipeline.addLast("deflater", new HttpContentCompressor(9));
pipeline.addLast("handler", new HttpProxyHandler());
关于这个问题,只有写入调用的顺序很重要,但要确保我构建了另一个 Handler ( HttpResponseWriteDelayHandler
),它会抑制writeComplete
事件,直到写入整个响应。
为了测试这一点,我在 Firefox 中启用network.http.proxy.pipelining
并访问了一个包含许多图像和连接的页面(一个新闻页面)。问题是,浏览器没有收到一些响应,尽管代理的日志认为它们已成功发送。
我有一些发现:
- 仅当从代理到服务器的连接比从代理到浏览器的连接快时才会出现此问题。
- 在该连接上发送更大的图像(例如 20kB)后,问题更常发生
- 如果仅发送响应,则不会发生此问题
304 - Not Modified
(刷新页面考虑浏览器缓存) - 设置
bootstrap.setOption("sendBufferSize", 1048576);
或以上没有帮助 writeComplete
在发送事件之前休眠一个取决于响应正文大小的时间帧HttpResponseWriteDelayHandler
可以解决问题,但这是一个非常糟糕的解决方案。