【发布时间】:2013-05-23 04:58:20
【问题描述】:
由这里回答的几个例子和问题引导(主要是 http://www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html?page=3 ),我想让服务器多次向客户端发送响应而不完成请求。当请求超时时,我创建另一个,依此类推。
我想避免长时间轮询,因为每次收到响应时我都必须重新创建请求。 (这完全不是 servlet 3.0 的异步功能所针对的)。
我在服务器端有这个:
@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<String, AsyncContext> 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<String, AsyncContext> store = AppContext.getInstance().getStore();
AsyncContext ac = store.get(id);
try {
ac.getResponse().getWriter().print(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是当我发出请求时,只有当我调用ac.complete() 时才会发送数据。没有它,请求将始终超时。所以基本上我想在请求完成之前“流式传输”数据。
只是为了说明一下,我已经尝试使用Jetty 8 继续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);
至少有人可以确认服务器端没问题吗? :)
【问题讨论】:
-
你能发布你的xml配置吗?
-
这个 servlet 没有 XML 配置,它的 3.0 规范并配置了注释(见上文,asyncSupported = true)但是,如果我将其设置为 false,则 servlet 在
startAsync()行上失败。所以它的配置很好。此外,当我从 cmd 运行curl到该地址时,它按预期以块的形式显示数据。所以我的结论是客户端的JS代码是错误的。 -
这对你有用吗?
-
不,它没有。抱歉我没有早点回复。我用 jQuery .ajax 调用和 XMLHttpRequest 都试过了。请求待处理,永远不会触发
readystatechange。 -
Nob,你能告诉我我的新答案是否适合你吗?或者你有没有想出其他方法来解决它?无论如何,我有兴趣知道。谢谢!
标签: java jakarta-ee servlets servlet-3.0 server-push