Java Servlet 3.0服务器推送:使用相同的AsyncContext多次发送数据 [英] Java Servlet 3.0 server push: Sending data multiple times using same AsyncContext

查看:149
本文介绍了Java Servlet 3.0服务器推送:使用相同的AsyncContext多次发送数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Lead by several examples and questions answered here ( mainly http://www.javaworld.com/javaworld/jw-02-2009/jw-02-servlet3.html?page=3 ), I want to have server sending the response multiple times to a client without completing the request. When request times out, I create another one and so on.

我想避免长轮询,因为每次收到响应时我都要重新创建请求。 (并且这不是servlet 3.0的异步功能所针对的)。

I want to avoid long polling, since I have to recreate request every time I get the response. (and that quite isn't what async capabilities of servlet 3.0 are aiming at).

我在服务器端有这个:

@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);

    }
}

以及写入异步的线程上下文。

And a thread to write to async context.

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()时才会发送数据。没有它,请求将永远超时。所以基本上我想在请求完成之前将数据流式传输。

But when I make the request, data is sent only if I call ac.complete(). Without it request will always timeout. So basically I want to have data "streamed" before request is completed.

只是为了记笔记,我试过这个用 Jetty 8 延续 API ,我也试过打印到 OutputStream 而不是 PrintWriter的。我还在响应时尝试了 flushBuffer()。同样的事情。

Just to make a note, I have tried this with Jetty 8 Continuation API, I also tried with printing to OutputStream instead of PrintWriter. I also tried flushBuffer() on response. Same thing.

我做错了什么?

客户端是这样完成的:

    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);

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

Can someone at least confirm that server side is okay? :)

推荐答案

您的服务器端和客户端代码确实没问题。
问题实际上是您的浏览器缓冲来自您的网络服务器的 text / plain 响应。
这是你在使用curl时没有看到这个问题的原因。

Your server-side and client-side code is indeed ok. The problem is actually with your browser buffering text/plain responses from your web-server. This is the reason you dont see this issue when you use curl.

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

I took your client-side code and I was able to see incremental responses, with only just one little change:

response.setContentType("text/html");

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

The incremental responses showed up immediately regardless of their size.

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

Without that setting, when my output was a small message, it was considered as text/plain and wasnt showing up at the client immediately. When I kept adding more and more to the client responses, it got accumulated until the buffer size reached about 1024 bytes and then the whole thing showed up on the client side. After that point, however, the small increments showed up immediately (no more accumulation).

这篇关于Java Servlet 3.0服务器推送:使用相同的AsyncContext多次发送数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆