http://www.perlmonks.org?node_id=161696

belize has asked for the wisdom of the Perl Monks concerning the following question:

I have a cgi that has a number of subroutines to perform after a form input. At the end of each subroutine, I would like a message output to the monitor immediately instead of waiting for all subroutines to complete before printing to screen.

In other words, when subroutine#1 is complete, the message "# 1 complete..." would appear on the monitor, then say 2 seconds later when subroutine#2 is complete, the message "#2 complete..." would appear, and so on.

I've seen this on a number of occassions but can't locate the proper commands/syntax .

Thanks.

Edit kudra, 2002-05-01 Added (CGI) to title

Replies are listed 'Best First'.
Re: output to screen in real time
by perlplexer (Hermit) on Apr 24, 2002 at 18:04 UTC
    At the beginnning of your CGI script, set autoflush to 1
    $|++; # like this
    --perlplexer
      Is the output sent to the monitor via the "Print" statement or some other means?
Re: output to screen in real time
by belg4mit (Prior) on Apr 24, 2002 at 18:21 UTC
    There are a few ways of doing this. None is going to be perfect. As already suggested you need to set autoflush. Likewise you need to end each print with a newline, IIRC some browsers will not render a line until a newline is received (or the document closed). Likewise, your status messages cannot be embedded in a table, would usually have to wait for the table to be closed to be able to render properly. And finally I think a browser may disconnect afterawhile if not data is being received, if these processes take too long you'll have to print to keep the connection open (whitespace would be your best bet).

    Another means of doing this is server-push, last I checked it was only supported by Netscape though (it uses the multipart/x-mixed-replace MIME-type).

    --
    perl -pew "s/\b;([mnst])/'$1/g"

      Another means of doing this is server-push, last I checked it was only supported by Netscape though (it uses the multipart/x-mixed-replace MIME-type).
      A different method, for IE, is to use client-pull with the active-x object Microsoft.XMLHTTP. As bad as A-X is security wise, this one seems the most benign. Of course, this requires some client-sever communication: Either you need to separate all of your subs, and call each cgi separately, or pass a q-string down to the server and route the cgi execution based on the parameter:

      Accessed via javascript:
      <script language=javascript> var url="nameOfCgi.pl" var httpObj = new ActiveXObject('Microsoft.XMLHTTP'); httpObj.open (GET,url,false); httpObj.send(); return (httpObj); //httpObj.responseText contains the returned html. </script>
Re: output to screen in real time
by jsprat (Curate) on Apr 24, 2002 at 19:14 UTC
    The answers already given are great. However, some web servers buffer output from CGI scripts (Apache hasn't buffered CGI output since 1.2, quite a while ago;). If you are still having a problem after , check your web server documentation for "non-parsed headers".

    Also, remember that this is never guaranteed to work 100% of the time - connectivity can be lost, the user's computer can lose power, etc. etc. You may want to consider another way of communicating the results in addition to this. Maybe email, or another page to view status?

    Good luck

Re: output to screen in real time
by Silicon Cactus (Scribe) on Apr 24, 2002 at 19:54 UTC

    Just a thought, nothing more, but it might be prudent to mention that the abovementioned answers will not work with a templating system... unless I am mistaken, which I may be.

    Verification anyone?

      You could certainly do server push with templating. I would have to say no for persistent print.

      --
      perl -pew "s/\b;([mnst])/'$1/g"

(cLive ;-) Re: output to screen in real time
by cLive ;-) (Prior) on Apr 24, 2002 at 20:47 UTC
    and don't show the output within a table - it usually won't render until table is completed.

    cLive ;-)