2013-05-10 48 views
0

我正在写HTTP Web服务,可能需要相当长的时间来产生结果。我使用嵌入式Jetty 8.1.5和JAX-RS(Apache CXF)如何控制码头中的块?

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

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

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

正如我所看到的,我需要一种方式来告诉码头“请完成当前块并冲洗它”,但不知道如何。

回答

1

其实我不确定你的问题是块。如果我找到了你的答案,你正在写进度到结果终于去的同一个流?

只需调用响应中的flushBuffers,就可以使用或不使用chunking。

然而,它取决于你的连接和你的浏览器,如果这使它进入客户端。 透明代理可能会聚合内容并且不会刷新,直到响应完成或其自己的缓冲区已满。浏览器可能不会处理任何内容,直到响应完成或缓冲区已满。

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

你最好使用类似于服务器发送的事件,websocket或长轮询的方式向客户端发送进度.....更好 - 只需使用cometd.org,它将为客户端选择最佳传输可用。

+0

的确,问题实际上是Apache CXF在我们使用的版本中存在一个错误,它只是忽略了flush()调用。 – relgames 2013-05-18 16:29:25

1

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

+0

它不起作用,消息仍然被缓冲。 – relgames 2013-05-11 13:16:45

+0

请参阅下面的回复。你的问题不是组块。 – gregw 2013-05-17 00:15:25