【问题标题】:Unknow length of Http Response未知长度的 Http 响应
【发布时间】:2012-05-12 01:12:21
【问题描述】:

我们知道在Java EE servlet/jsp 中,客户端对于一个http 请求可以获得一个http 响应。我想实现一些http响应长度未知的东西。在客户端发送第一个 http 请求后,我希望服务器继续为客户端推送数据。在那种情况下,我不想使用 AJAX,因为 AJAX 的重量很重。

例如,我想创建一个可以从 Web 服务器检索 Log Message 的网页,当从另一个模块生成 Log 消息时,Web 服务器可以发送 Log 消息(所以在这种情况下,时间间隔是未知,我们假设这里不推荐定期检查计时器)。日志消息附加到 Web 浏览器,这意味着 Web 浏览器无法刷新,例如:

日志下午 12:00 ..... 日志 12:03 pm ..... 日志 12:04 pm ..... . . .

我怎样才能通过仅发送一个 http 请求并继续检索 http 响应来做到这一点?


@dystroy

你的意思是,我可以在 doPost/doGet 结束之前多次刷新打印机(当有新的日志数据时)?

请忽略语法错误!我没有使用 IDE。

protected void doPost(HttpServletRequest req, HttpServletResponse resp){

    PrintWriter pw = resp.getWriter();

    pw.println("<html><body>Testing for the streaming.</body></html>");
    pw.flush();


    /*
    The syntax could not be correct, please focus on logic.
    This while loop check the log sent by web server is finised or not and flush the data to the 
    client, after that the javascript will change the content of the inner Html. Is the logic below
    valid?
    */
    while(!log.finish()){
        pw.println("document.setInnerHtml("+log.newLog()+")");
        pw.flush(); 
    }

}

【问题讨论】:

    标签: jsp jakarta-ee servlets


    【解决方案1】:

    您当然需要考虑使用keep-alive

    它允许客户端重复使用现有连接从服务器连续读取数据。下面,只是从下面列出的链接中复制了示例。

    try {
        URL a = new URL(args[0]);
        URLConnection urlc = a.openConnection();
        is = conn.getInputStream();
        int ret = 0;
        while ((ret = is.read(buf)) > 0) { // here it try to read response using existing connection.
          processBuf(buf);
        }
        // close the inputstream
        is.close();
    } catch (IOException e) {
        try {
            respCode = ((HttpURLConnection)conn).getResponseCode();
            es = ((HttpURLConnection)conn).getErrorStream();
            int ret = 0;
            // read the response body
            while ((ret = es.read(buf)) > 0) {
                processBuf(buf);
            }
            // close the errorstream
            es.close();
        } catch(IOException ex) {
            // deal with the exception
        }
    }
    

    使用上面显示的技术来加载日志文件。

    这里有一个很好的解释:Persistent Connection


    另一个选项很简单,考虑制作Ajax Request

    【讨论】:

    • 感谢您的文章。我将如何在 servlet/jsp 中尝试同样的事情?我无法将文章链接到如何在 servlet/jsp 中实现这一点。能给我更多的线索吗?
    【解决方案2】:

    您总是可以使用长的 http 答案并定期刷新它们,它可以工作,至少在网络上出现短问题之前是有效的。您不必在 HTTP 标头中发送答案的长度。

    正确的解决方案是使用 ajax 进行一些拉动或使用 websockets,它们非常轻巧快速,但并非所有浏览器都支持(请参阅 http://caniuse.com/websockets)。

    关于“重量级”的 ajax,请注意,成本本质上是 http 查询+答案之一。如果您不要求小于 100 毫秒的延迟并且具有正常连接,您会发现 ajax 相当快(更喜欢使用 servlet 而不是 jsp)。只是不要将您的日志封装成过于繁重的格式。

    【讨论】:

    • 您好,我无法在此处添加代码,您能帮我检查一下上面的代码吗?是不是和你说的差不多。
    • 我没有测试它,但你的代码似乎是正确的。你试过了,有问题吗?正如我试图解释的那样,这种方法确实有效,但效果不是很好,尤其是在网络不好或者你长时间停止写作的情况下。
    • 我待会回家试试。顺便说一句,我是否应该按照另一位评论者的建议将连接设置为“保持活动状态”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-26
    相关资源
    最近更新 更多