Java Servlet 3.0服务器推送:使用相同的AsyncContext多次发送数据

通过这里回答的几个例子和问题(主要是http://www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html?page=3 ),我想让服务器发送多个响应没有完成请求的客户的时间。 当请求超时时,我创建另一个,依此类推。

我想避免长时间轮询,因为每次得到响应时我都必须重新创建请求。 (而且这不是servlet 3.0的异步function所针对的)。

我在服务器端有这个:

@WebServlet(urlPatterns = {"/home"}, name = "async", asyncSupported = true) public class CometServlet extends HttpServlet { public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException { AsyncContext ac = request.startAsync(request, response); HashMap store = AppContext.getInstance().getStore(); store.put(request.getParameter("id"), ac); } } 

还有一个写入异步上下文的线程。

 class MyThread extends Thread { String id, message; public MyThread(String id, String message) { this.id = id; this.message = message; } public void run() { HashMap store = AppContext.getInstance().getStore(); AsyncContext ac = store.get(id); try { ac.getResponse().getWriter().print(message); } catch (IOException e) { e.printStackTrace(); } } } 

但是当我发出请求时,只有在我调用ac.complete()才会发送数据。 没有它,请求将永远超时。 所以基本上我想在请求完成之前将数据“流式传输”。

只是为了做一个注释,我已经尝试使用Jetty 8 Continuation API ,我也试过打印到OutputStream而不是PrintWriter 。 我也在响应时尝试了flushBuffer() 。 一样。

我究竟做错了什么?

客户端是这样完成的:

  var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://localhost:8080/home', true); xhr.onreadystatechange = function () { if (xhr.readyState == 3 || xhr.readyState == 4) { document.getElementById("dynamicContent").innerHTML = xhr.responseText; } } xhr.send(null); 

有人至少可以确认服务器端是否正常? 🙂

您的服务器端和客户端代码确实没问题。 问题实际上是您的浏览器缓冲来自您的Web服务器的文本/简单响应。 这是您使用curl时没有看到此问题的原因。

我拿了你的客户端代码,我能够看到增量响应, 只有一点变化:

 response.setContentType("text/html"); 

无论大小如何,增量响应都会立即出现。

没有这个设置,当我的输出是一个小消息时,它被认为是text / plain并且没有立即显示在客户端。 当我不断向客户端响应中添加越来越多的内容时,它会累积到缓冲区大小达到大约1024字节 ,然后整个东西出现在客户端。 然而,在那之后,立即出现小增量(不再累积)。

我知道这有点旧,但你也可以在响应上刷新。