SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Enthusiast sffc's Avatar
    Join Date
    Jul 2006
    Posts
    90
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Arrow PHP Header for Timeout?

    I am programming an AJAX web application, but I am encountering a potential problem regarding timeouts. Some browsers (notably Safari) will "wait" only 1 minute for a request to be sent back from PHP. Here is a bit of my code:

    PHP Code:
    $initquery "select * from MyTable..."// a MySQL query
    do{
        
    sleep(1);
        
    $result mysql_query($initquery);
        
    $result mysql_fetch_assoc($result);
    }while(
    $result["continue"]=="no"); 
    The code works fine. The problem is, if $result["continue"] does not change to "yes" within a minute (this is done by other scripts), the browser will stop waiting and issue a timeout error. Is there a way to make the browser wait longer for a response? I was thinking that this could be done with some kind of header that sets timeout at five minutes or something (like header('Cache-Control: no-cache, must-revalidate'); makes the browser not cache the page). Is this possible? Thanks in advance.

    .
    "I haven't failed, I just found
    100,000 ways that don't work"
    Thomas Edison

  2. #2
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    To defeat caching for AJAX, add a random string to the request query string:

    Code:
    function randomString(len) {
     var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
     var rand = "";
     for (var i=0;i < len;i++) {
      var pos = Math.floor(Math.random() * chars.length);
      rand += chars.substring(pos,pos + 1);
     }
     return rand;
    }
    
    req.open('GET','/some_script.php?rand=' + randomString(16),true);

  3. #3
    SitePoint Enthusiast sffc's Avatar
    Join Date
    Jul 2006
    Posts
    90
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks, but that is not my question. My question is how to make the browser not time out the AJAX request if it takes more than a minute.
    "I haven't failed, I just found
    100,000 ways that don't work"
    Thomas Edison

  4. #4
    SitePoint Guru
    Join Date
    Jul 2005
    Location
    Orlando
    Posts
    634
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by World Wide Weird View Post
    To defeat caching for AJAX, add a random string to the request query string:

    Code:
    function randomString(len) {
     var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
     var rand = "";
     for (var i=0;i < len;i++) {
      var pos = Math.floor(Math.random() * chars.length);
      rand += chars.substring(pos,pos + 1);
     }
     return rand;
    }
    
    req.open('GET','/some_script.php?rand=' + randomString(16),true);
    Or just use a post request. But, as the OP said, that wasn't the question.

  5. #5
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sffc View Post
    Thanks, but that is not my question. My question is how to make the browser not time out the AJAX request if it takes more than a minute.
    Okay. The answer to the second part of your question - whether cache control headers will increase the timeout - is no. Cache control headers aren't even 100% effective at preventing client-side caching.

    For the first part - how to increase the timeout - there is a way to do it, but I've forgotten how at the moment. If I recall correctly, it has something to do with setting a property on the XMLHttpRequest object itself rather than setting a certain HTTP header. I am looking through some old code I wrote and will let you know if and when I come across it. I rather doubt it still exists though, because my solution was probably to make my server-side script not take so long to render a response in the first place.

  6. #6
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    All of the information I can find about AJAX timeouts pertains to specific JavaScript frameworks such as Prototype. I'm guessing this is not what you want. Since the XMLHttpRequest object does not have any properties or methods for explicitly handling timeouts, these frameworks apparently handle them in a roundabout way. So let's have a look at another approach.

    What you could try is to have your onstatechange handler detect whether the status code is 408 (Request Timeout) or 504 (Gateway Timeout) and retry the request accordingly. IMHO, it would be better to use such a client-side approach rather than cause your server-side script to sleep while waiting for a certain condition to be met. In other words, push the overhead off onto the client rather than incurring the overhead on your server.

  7. #7
    SitePoint Enthusiast sffc's Avatar
    Join Date
    Jul 2006
    Posts
    90
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by World Wide Weird View Post
    What you could try is to have your onstatechange handler detect whether the status code is 408 (Request Timeout) or 504 (Gateway Timeout) and retry the request accordingly.
    I made a for..in at the end of my javascript alert all the properties of the current XMLHttpRequest. readyState=4, status=0, and all other properties are null. I can tell when the request has timed out by the fact that responseText="" rather than something else. If the status code is 0, what does that mean? There's a big difference between 0, 408 and 504 (not that that means anything).

    Quote Originally Posted by World Wide Weird View Post
    IMHO, it would be better to use such a client-side approach rather than cause your server-side script to sleep while waiting for a certain condition to be met. In other words, push the overhead off onto the client rather than incurring the overhead on your server.
    Question: Does a script sleeping use many server resources? If not, it seems that a client-side script that asked for the information every few seconds would use more server and client resources than having the client "sit tight" as the server sleeps at 1-second intervals. Just a mini-analogy: is it more efficient for someone to ask a teacher if it is lunchtime yet constantly at 5-second intervals, or for someone to ask once and wait as the teacher checks every few seconds and finally says "yes"? This probably is not how server-side scripts work, but it is a nice analogy, if I don't say so myself

    As for the frameworks, do they essentially "look out" for when the script times out and refresh it automatically? What do they actually do?

    Thank you very much for the help that you have given me so far. Unless there is a better solution, I will probably have the script make a new request when the old one times out (essentially what you suggested in the first quote above). Again, thank you for your help and ideas thus far
    "I haven't failed, I just found
    100,000 ways that don't work"
    Thomas Edison

  8. #8
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sffc View Post
    I made a for..in at the end of my javascript alert all the properties of the current XMLHttpRequest. readyState=4, status=0, and all other properties are null. I can tell when the request has timed out by the fact that responseText="" rather than something else. If the status code is 0, what does that mean? There's a big difference between 0, 408 and 504 (not that that means anything).
    XMLHttpRequest is not a native JavaScript object, so iterating over its properties with for...in is not guaranteed to work. This is especially true in Internet Explorer, where browser objects are wrapped in an ActiveX object interface. Try using a reporting agent such as Live HTTP Headers or Firebug (both Firefox extensions) to see what, if any, response headers the server is actually sending.

    Quote Originally Posted by sffc View Post
    Question: Does a script sleeping use many server resources?
    Strictly speaking, no it doesn't. However, it keeps a TCP socket tied up while handling the request. If many visitors are using the AJAX application at once and it takes a long time to complete each request, the server could experience something akin to a mild DDoS attack.

    Quote Originally Posted by sffc View Post
    As for the frameworks, do they essentially "look out" for when the script times out and refresh it automatically? What do they actually do?
    I am not sure exactly how they accomplish it. Like you, I'd rather write my own code than hack the dozens of JavaScript frameworks that have proliferated in recent years. Since XMLHttpRequest doesn't provide any "hooks" for controlling timeouts, I'm guessing that they do something similar to what you describe.

  9. #9
    SitePoint Enthusiast sffc's Avatar
    Join Date
    Jul 2006
    Posts
    90
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Just a little update: I ended up making a javascript that checks with PHP every 2 seconds. It seems to work well.

    I discovered that, if the client for some reason closed their browser in the middle of a request, the script would keep running for no reason. So, if the condition that would trigger the stopping of the sleep was never met, it would in fact start to slow down the server. Additionally, if the user ever used the same AJAX file again, it would not give them a response; rather, it would keep sleeping until the "overdue" condition was met.

    Thank you very much for your help as I worked though this problem. Maybe you'll be using my AJAX application/game in the future
    "I haven't failed, I just found
    100,000 ways that don't work"
    Thomas Edison

  10. #10
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by sffc View Post
    I discovered that, if the client for some reason closed their browser in the middle of a request, the script would keep running for no reason.
    You can check for a user abort with the aptly named connection_aborted function and act accordingly. Immediately after waking up from the sleep call would be a good time to do it.

    Quote Originally Posted by sffc View Post
    Maybe you'll be using my AJAX application/game in the future
    It will be interesting to see how it turns out. Keep us informed.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •