没有keep-alive的Jetty chunked传输编码

时间:2014-10-09 15:20:04

标签: asynchronous jetty

我使用Jetty作为服务器通过HTTP传输数据。数据来自消息队列,我以异步方式处理处理,在连接准备就绪时打印消息,并且有消息可用。当客户端断开连接时,我停止从队列中消费消息并清理专用于该流的所有资源。

Jetty选择发送响应块并默认设置Transfer-Encoding: chunked - 这就是我想要的,因为这是一个无休止的流,我显然无法设置Content-Length标头。

但是,我还需要在响应中设置Connection: close。服务器将在负载均衡器后面运行,该负载均衡器将尝试与后端服务器保持持久连接,除非他们明确发送Connection: close。我没办法配置负载均衡器,它完全不在我手中。如果负载均衡器保持连接打开,我无法知道何时停止从消息队列中消耗,因为连接将保持打开状态。

问题在于,当我执行response.setHeader("Connection", "close")时,Jetty会停止将响应呈现为分块。它也没有设置Content-Length标头,只是将输出流式传输到连接。据我所知,这在HTTP中并不合适,即使许多客户端可能会处理它。我真的想使用分块传输编码,并禁用keep-alive。我怎么能说服Jetty呢?

这是一个显示我的工作的最小例子。如果我删除设置Connection标题的行Jetty块响应,但是它没有。

public class StreamingServer {
  public static void main(String[] args) throws Exception {
    Server server = new Server(2000);
    server.setHandler(new AbstractHandler() {
      public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        response.setBufferSize(1024);
        // if I remove this line I get Transfer-Encoding: chunked
        response.setHeader("Connection", "close");
        response.flushBuffer();
        AsyncContext asyncContext = request.startAsync();
        asyncContext.setTimeout(0);
        final ServletOutputStream out = response.getOutputStream();

        // start consuming messages from the message queue here

        out.setWriteListener(new WriteListener() {
          public void onError(Throwable t) {
            // stop consuming messages and clean up resources
          }

          public void onWritePossible() throws IOException {
            while (out.isReady()) {
              // send the next available message from the queue
              out.print(...);
            }
          }
        });
      }
    });
    server.start();
    server.join();
  }
}

0 个答案:

没有答案