0

我正在编写可能需要很长时间才能产生结果的 HTTP Web 服务。我使用嵌入式 Jetty 8.1.5 和 JAX-RS (Apache CXF)

我决定采用某种控制协议:当新请求到来时,我在一个单独的线程中开始一个长时间运行的作业,并定期以当前状态写入 HttpOutputStream 行(“CONTROL_MESSAGE:42% 完成”)

问题是 Jetty 在这里使用块编码,所以我的状态消息被缓冲并且没有用,因为它们都可以缓冲在一个块中,为客户端提供没有进展。

我不能使用 Content-Length 属性,因为我不知道最终结果的长度。HttpOutputStream.flush() 不起作用,因为 Jetty 使用内部缓冲区。

正如我所看到的,我需要一种方法来告诉 Jetty“请完成当前块并刷新它”,但不知道如何。

4

2 回答 2

1

其实我不确定你的问题是分块。如果我猜对了,您正在将进度写入结果最终会到达的同一流中吗?

这可以通过在响应上调用 flushBuffers 来完成或不分块。

但是,这取决于您的连接和浏览器是否进入客户端。透明代理可以聚合内容并且在响应完成或自己的缓冲区已满之前不会刷新。在响应完成或其缓冲区已满之前,浏览器可能不会对任何内容进行操作。

在使用这种技术的彗星的某些实现中,您必须在推送消息之后发送 512 个字节的空白。

您最好使用诸如服务器发送事件、websocket 或长轮询之类的东西来向客户端发送进度......更好的是 - 只需使用 cometd.org,它将为可用的客户端选择最佳传输。

于 2013-05-17T00:13:55.080 回答
1

您应该能够通过在响应中添加 Connection: close 标头来禁用持久连接本身来禁用分块,就是这样或提前知道 Content-Length。或者我想你也可以使用 HTTP/1.0。我将使用码头文档打开一个错误,以便更好地记录这一点。

于 2013-05-10T18:49:07.890 回答