views:

544

answers:

5

Hi, I have written within a JSP page to have Thread.sleep() for more than 1 hour. The JSP is deploayed on WebLogic server 9.2. I am trying to check the browser timeout and page cannot be displayed error.

As per the below documentation, the default timeout for IE6 is 60 seconds. However, I was testing the above JSP and did not get any timeout or page cannot be displayed even beyond 30 minutes. I am doing this to the user experience for a requirement that can take long time to execute. Thanks.

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

A: 

Your page may have returned some amount of data (such as headers) which convinced IE to leave the socket open and wait for more data.

To see what's actually going on, try running Wireshark (or Fiddler) on the machine with IE. You could also telnet to port 80 on your server and request the page manually (type in GET /path/to/your.jsp HTTP/1.0 followed by 2 line breaks).

Seth
+1  A: 

I think you need to use AJAX technology to solve this kind of long operation problem, ask Server to maintain a connection over an hour is not an efficient decision.

What if more than hundred users connect to your server?

The concept of a simple AJAX solution is like this:

  1. you start a timer using Javascript's setTimeInterval().
  2. in timer's invocation, you compose a URL and use a XmlHttpRequest to request your server.
  3. this async request will trigger(or just ask) a progress of a server-side back-end service.
  4. every time the JS timer ticks, server-side should respond the progress(or result) to give user a visual response.

I think this is a better way to do your job. you can build this mechanism by your own or use some existing AJAX Framework like GWT, DWR even ZK to accomplish it.

Zanyking
A: 

Typically the "this page cannot be displayed" message occurs when the browser fails to make a connection to the host. In the scenario you've presented, the browser manages to make a connection and holds that connection open until the connection finishes or the server side hangs up.

If you are trying to test the functionality of the browser, you'll need to play some tricks on the network to have the connection fail. For example, firewall port 80 on your server such that it doesn't respond to any packets sent its way. The browser should leave the socket open for 60 seconds waiting for a response. When the response doesn't arrive the "this page cannot be displayed" message should be displayed.

Bryan Kyle
I am getting page cannot be displayed after an hour. Its confusing why I am not getting after 60 seconds.
stranger001
Maybe the server did return response headers and the client is now waiting for the response body.
BalusC
+2  A: 

If you want to run and control a long-running process, better let it run in its own Thread instead of the request's Thread. Store a reference to this Thread in the session scope so that the client can use ajaxical requests (using the same session!) to request the server side for the current progress (and automagically also to keep the session alive so that it doesn't timeout).

Here's a basic example of such a 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;
    }

}

..which is mapped as follows:

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

And here's a basic example of the JSP (with a little shot jQuery, an ajaxical JS framework which I by the way greatly recommend):

<!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"&gt;&lt;/script&gt;
        <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>

Open it at http://localhost:8080/yourcontext/runLongProcess and click the button.

If this is a really, really long running process, you may improve "efficiency" by increasing the ajax intervals to 5 seconds or so so that the server doesn't feel getting DDOS'ed ;)

Hope this helps.

BalusC
Thanks for providing the above code. My intention is not to test a thread, but was checking what if a request takes very long time may be an hour. I would wanted to check how the browser or servers behave and any exceptions are thrown.
stranger001
It is a bad practice to abuse the request thread for this purpose. The task should be done in a "background running thread". The ajaxical requests also help in keeping the session alive so that it doesn't get timed out after (default) 30 minutes.
BalusC
A: 

Hi, Thanks for all your answers. We have a requirement where the users can wait longer. We are limiting the number of parallel requests by configuration in server (using Work Manager in WebLogic). If the number of parallel requests is more than the max no of threads, the requests are placed in queue. My questions if if the browser times out after 60 seconds as specified in the link - http://support.microsoft.com/kb/181050. We have done few tests and observing that page cannot be displayed message is displayed after 1 hour. We also checked response headers and no response content or response headers are returned back. So, we are not sure if either the server is timing our or browser is timing out. And also would like to check if IE6 times out after an hour or after 60 seconds as per the documentation.

Thanks

stranger001
Sorry, but it is just **wrong** to run a 1 hour query in a browser. You should implement this long running process as an asynchronous process as I wrote in http://stackoverflow.com/questions/1676199/work-managers-threads-constraint-and-page-cannot-be-displayed/1678440#1678440
Pascal Thivent