浏览器超时和页面无法显示

时间:2009-11-05 03:23:04

标签: java jsp multithreading

我已经在JSP页面中编写了Thread.sleep()超过1小时。 JSP在WebLogic Server 9.2上展开。我试图检查浏览器超时和页面无法显示错误。

根据以下文档,IE6的默认超时为60秒。但是,我正在测试上面的JSP并没有得到任何超时或页面甚至超过30分钟也无法显示。我这样做是为了满足用户体验需求,这可能需要很长时间才能执行。感谢。

http://support.microsoft.com/kb/181050

5 个答案:

答案 0 :(得分:3)

如果您想要运行和控制长时间运行的流程,最好让它在自己的Thread而不是请求的Thread中运行。在会话范围中存储对此Thread的引用,以便客户端可以使用ajaxical请求(使用相同的会话!)来请求服务器端获取当前进度(并自动保持会话处于活动状态以便它没有超时)。

以下是这种servlet的基本示例:

package mypackage;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RunLongProcessServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        if ("XMLHttpRequest".equals(request.getHeader("x-requested-with"))) {
            LongProcess longProcess = (LongProcess) request.getSession().getAttribute("longProcess");
            response.setContentType("application/json");
            response.getWriter().write(String.valueOf(longProcess.getProgress()));
        } else {
            request.getRequestDispatcher("runLongProcess.jsp").forward(request, response);
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException
    {
        LongProcess longProcess = new LongProcess();
        longProcess.setDaemon(true);
        longProcess.start();
        request.getSession().setAttribute("longProcess", longProcess);
        request.getRequestDispatcher("runLongProcess.jsp").forward(request, response);
    }

}

class LongProcess extends Thread {

    private int progress;

    public void run() {
        while (progress < 100) {
            try { sleep(1000); } catch (InterruptedException ignore) {}
            progress++;
        }
    }

    public int getProgress() {
        return progress;
    }

}

..映射如下:

<servlet>
    <servlet-name>runLongProcess</servlet-name>
    <servlet-class>mypackage.RunLongProcessServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>runLongProcess</servlet-name>
    <url-pattern>/runLongProcess</url-pattern>
</servlet-mapping>

这是JSP的一个基本示例(带有一个小镜头jQuery,这是一个令我非常推荐的ajaxical JS框架):

<!doctype html>
<html lang="en">
    <head>
        <title>Show progress of long running process with help of Thread and Ajax.</title>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(init);

            function init() {
                if (${not empty longProcess}) {
                    $.progress = 0;
                    checkProgress();
                }
            }

            function checkProgress() {
                $.getJSON('runLongProcess', function(progress) {
                    $('#progress').text(progress);
                    $.progress = parseInt(progress);
                });
                if ($.progress < 100) {
                    setTimeout(checkProgress, 1000);
                }
            }
        </script>
    </head>
    <body>
        <form action="runLongProcess" method="post">
            <p>Run long process: <input type="submit"></p>
            <p>Current status: <span id="progress">0</span>%</p>
        </form>
    </body>
</html>

http://localhost:8080/yourcontext/runLongProcess打开它,然后点击按钮。

如果这是一个真正长期运行的过程,你可以通过将ajax间隔增加到5秒左右来提高“效率”,这样服务器就不会感觉到DDOS了;)

希望这有帮助。

答案 1 :(得分:0)

您的页面可能已经返回了一些数据(例如标题),这些数据说服IE让套接字保持打开并等待更多数据。

要了解实际发生的情况,请尝试使用IE在计算机上运行Wireshark(或Fiddler)。您也可以telnet到服务器上的端口80并手动请求页面(键入GET /path/to/your.jsp HTTP/1.0,然后输入2个换行符)。

答案 2 :(得分:0)

我认为你需要使用AJAX技术来解决这种长时间的操作问题,要求Server维持一个小时的连接并不是一个有效的决定。

如果有超过一百个用户连接到您的服务器怎么办?

简单的AJAX解决方案的概念是这样的:

  1. 使用Javascript的setTimeInterval()启动计时器。
  2. 在计时器的调用中,您组成一个URL并使用XmlHttpRequest来请求您的服务器。
  3. 此异步请求将触发(或仅询问)服务器端后端服务的进度。
  4. 每次JS计时器滴答时,服务器端都应响应进度(或结果)以向用户提供可视响应。
  5. 我认为这是一种更好的工作方式。你可以自己构建这个机制,也可以使用像GWT,DWR甚至ZK这样的现有AJAX框架来实现它。

答案 3 :(得分:0)

通常,当浏览器无法与主机建立连接时,会出现“此页面无法显示”消息。在您提供的方案中,浏览器设法建立连接并保持该连接打开,直到连接完成或服务器端挂起。

如果您尝试测试浏览器的功能,则需要在网络上玩一些技巧以使连接失败。例如,服务器上的防火墙端口80,使其不响应任何发送方式的数据包。浏览器应该让套接字打开60秒等待响应。当响应未到达时,应显示“此页面无法显示”消息。

答案 4 :(得分:0)

感谢您的所有答案。我们有一个要求,用户可以等待更长时间。我们通过服务器中的配置限制并行请求的数量(使用WebLogic中的Work Manager)。如果并行请求数大于最大线程数,则请求将放入队列中。我的问题是,如果浏览器在链接后指定的60秒后超时 - http://support.microsoft.com/kb/181050。我们做了很少的测试并观察到页面无法显示1小时后显示消息。我们还检查了响应标头,并且没有返回响应内容或响应标头。因此,我们不确定服务器是否正在计时或浏览器是否超时。并且还想根据文档检查IE6在一小时后或60秒后是否超时。

由于