Skip to main content

Adding Timeout to Http access

No replies
earamsey
Offline
Joined: 2004-04-15
Points: 0

Hello,

I am trying to add timeout to http access but I am having a few problems. here is the code model that I am using.

--- class HttpMgr ---

public final class HttpMgr<br />
{<br />
    public static void post (String sURL, String sPostData, HttpListener httpListener)<br />
    {<br />
//#if DUMP_HTTP_URL=="on"<br />
//# 	System.out.println("HttpMgr2.java::post() - \n\tURL:"+sURL+"\n\tPost Data:\n\t\t"+sPostData);<br />
//#endif</p>
<p>        if (sPostData == null || sPostData.length () == 0)<br />
        {<br />
            int rc = ErrorMgr.noPost ();<br />
            httpListener.httpListener (rc, null);<br />
        }<br />
        else<br />
        {<br />
            if (!connectionThread.isAlive ())<br />
            {<br />
                startMgr ();<br />
            }</p>
<p>            synchronized (connectionThread)<br />
            {<br />
                connectionThread.connect (HttpConnection.POST, sURL, sPostData.getBytes (), httpListener);<br />
            }<br />
        }<br />
    }<br />
}

HttpMgr class has static methods. First, the midlet calls HttpMgr.startMgr() and this creates an instance of the class "ConnectionThread". ConnectionThread runs in the background and services Http requests; as shown above, when a Http post is requested the HttpMgr connects to the thread with the post data.

Here is connection thread code snippet;

public final class ConnectionThread extends Thread<br />
{<br />
    public void abort ()<br />
    {<br />
         // <CODE omitted for now> //<br />
    }</p>
<p>    public void run ()<br />
    {<br />
        while (isRunning)<br />
        {<br />
            try<br />
            {<br />
                // WAIT FOR A REQUEST<br />
                synchronized(this)<br />
                {<br />
                    isReady = true;<br />
                    wait ();<br />
                }</p>
<p>                if (isRunning)<br />
                {<br />
                    try<br />
                    {<br />
                        // SETUP and START TIMEOUT HANDLER //<br />
                        httpTimeoutTask = new HttpTimeoutTask (this);<br />
                        httpTimer = new HttpTimer (httpTimeoutTask);<br />
                        httpTimer.start ();</p>
<p>                        httpConnection = (HttpConnection) Connector.open (sURL, Connector.READ_WRITE, true );<br />
                        // <CODE to setup request headers not shown> //</p>
<p>                        if (doPost)<br />
                        {<br />
                            // <CODE to perform post not shown> //<br />
                        }</p>
<p>                        if (( rc = httpConnection.getResponseCode () ) == HttpConnection.HTTP_OK)<br />
                        {<br />
                            httpInputStream = httpConnection.openInputStream ();<br />
                            // <CODE to get data from input stream not shown> //<br />
                        }</p>
<p>                        // STOP THE TIMER<br />
                        httpTimer.stop ();<br />
                        httpTimer = null;<br />
                    }<br />
                    catch(Exception e)<br />
                    {<br />
                        //  //<br />
                    }<br />
                    finally<br />
                    {<br />
                        //  //<br />
                    }</p>
<p>                    // NOTIFY REQUEST OF HTTP REQUEST COMPLETION AND RETURN DATA<br />
                    httpListener.httpListener ( rc, s.length () == 0 ? null : s );<br />
                }<br />
            }<br />
            catch(Exception e)<br />
            {<br />
            }<br />
        }<br />
    }<br />
}

This particular portion, as indicated in above code snippet, of the code setups the Timeout handler;

<br />
                        httpTimeoutTask = new HttpTimeoutTask (this);<br />
                        httpTimer = new HttpTimer (httpTimeoutTask);<br />
                        httpTimer.start ();<br />

These are very simple classes defined as follows;

<br />
public class HttpTimeoutTask<br />
{<br />
    private ConnectionThread ct;</p>
<p>    public HttpTimeoutTask(ConnectionThread ct)<br />
    {<br />
        this.ct = ct;<br />
    }</p>
<p>    public void abort ()<br />
    {<br />
        ct.abort();<br />
    }<br />
}</p>
<p>public class HttpTimer implements Runnable<br />
{<br />
    public HttpTimer (HttpTimeoutTask httpTimeoutTask)<br />
    {<br />
        this.httpTimeoutTask = httpTimeoutTask;<br />
    }</p>
<p>    public void start ()<br />
    {<br />
        thread = new Thread(this);<br />
        thread.start ();<br />
    }</p>
<p>    public void stop()<br />
    {<br />
        //  //<br />
    }</p>
<p>    public void run ()<br />
    {<br />
        long timer = Constants.HTTP_TIMEOUT;<br />
        long decr = 60;</p>
<p>        isRunning = true;</p>
<p>        while (isRunning)<br />
        {<br />
            try<br />
            {<br />
                Thread.sleep (decr);<br />
            }<br />
            catch(Exception e)<br />
            {<br />
            }</p>
<p>            timer -= decr;<br />
            if (timer <= 0)<br />
            {<br />
                httpTimeoutTask.abort ();<br />
                isRunning = false;<br />
            }<br />
        }<br />
    }<br />
}

HttpTimeoutTask calls it's abort method if timer is <= 0. As shown above, HttpTimeoutTask calls the abort method of the ConnectionThread, here is the the abort method of the ConnectionThread;

<br />
public void abort ()<br />
{<br />
    try<br />
    {<br />
        if (httpConnection != null)<br />
        {<br />
            httpConnection.close ();<br />
            httpConnection = null;<br />
        }</p>
<p>        if (httpOutputStream != null)<br />
        {<br />
            httpOutputStream.close ();<br />
            httpOutputStream = null;<br />
        }</p>
<p>        if (httpInputStream != null)<br />
        {<br />
            httpInputStream.close ();<br />
            httpInputStream = null;<br />
        }<br />
    }<br />
    catch(Exception e)<br />
    {<br />
    }<br />
}<br />
According to documentation invoking the HttpConnection.close() method will cause an Exception to be thrown thus aborting the Http request.

I am having the following problems;
1. Timeout expires too fast, I defined HTTP_TIMEOUT to be "static final int HTTP_TIMEOUT = 60 * 30 * 1000;" this is 30 minutes. originally, the value "30" was 3 but it timed out even faster. Why is it not waiting the specified about of time? I realized the resolution of the Thread.sleep() is not accurrate but with a value of at least 5 it should be noticable, even then, value of 30 is not working either.

2.I display a busy cursor, just a sequence of images, on canvas during Http requests, however, the busy cursor thread appears to hang, and image sequence freezes, during Http access even though I have everything running in threads. Why is this? I tried this with Timer/TimerTask and the busy cursor thread still appeared to hang when device performed actual connection.

To test this I provided HttpMgr with an invalid URL. I am running this in the emulator and not on actually device but I assume that the device will perform exactly the same.

I would appreciate any help!

Thanks!