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

Is it possible to write things out to a web browser while it's actually happening in real time, rather than after the output of the entire script?
sub htmlOut(){ print CGI::header(); print '<html><head><title>Hello Test</title></head><body>'."\n +"; print $message; sleep (2); print $message; }
Like theoretically in the example above, that in the 2 seconds it takes to perform the sleep call, the first message would actually get displayed to the browser, then the second 2 seconds later?

I have a web cgi call that takes a while, and I'd like to make sure the browser session doesn't time out, and that the user can watch along during the function's execution.
Thanks!

Replies are listed 'Best First'.
Re: staggering html output
by McDarren (Abbot) on Oct 09, 2006 at 05:32 UTC
    You need to turn on auto-flushing, ie: $|=1;

    To get a good understanding of what goes on here, have a read of Suffering from Buffering, by MJD.

    Cheers,
    Darren :)

      It'll probably be sent out to the browser... but that doesn't mean that the browser will indeed try to display it. I've noticed that a browser tends to buffer whhat it gets back from the server, too. Usually it does work if you emit long strings, for example, several k of whitespace.

      Not ideal, of course.

Re: staggering html output
by holli (Abbot) on Oct 09, 2006 at 07:52 UTC
Re: staggering html output
by fenLisesi (Priest) on Oct 09, 2006 at 07:02 UTC
    If you are using mod_perl, also see rflush.
Re: staggering html output
by fmerges (Chaplain) on Oct 09, 2006 at 09:46 UTC

    Hi,

    To add one more :-), in Mason you use $m->flush_buffer.

    Regards,

    fmerges at irc.freenode.net
Re: staggering html output
by ecuguru (Monk) on Oct 12, 2006 at 05:36 UTC
    Hey guys and gals,
    Thanks for all the input. I tried the options above.
    $| = 1; didn't seem to do anything.
    rflush or flush ends all execution of the program cause I'm calling it wrong. Can you tell me how I call it from a cgi script where I'm just using print?
    The buffering website link didn't go anywhere
    I'm still parsing the link to the linux site to understand what they are doing

    I very well might be doing something wrong, so if you guys have any other suggestions, here is the entire code with the modifications requested. The flush seemed teh closest, is there anyway to flush and continue exection?
    if it helps, curl/wget, which I don't think buffer, both show the page downloading all at once. And I have no buffering or performance caching on my apache site.
    Thanks!
    #!/usr/bin/perl -w use strict; use CGI qw/:standard/; use CGI::Validate; $| = 1; &htmlOut(); exit; sub htmlOut(){ print CGI::header(); print '<html><head><title>Hello Test</title></head><body>'."\n +"; print time; print "<br>"; # flush(); #flush or rflush both end program here as it's + not a known function call sleep (1); print time; print "<br>"; sleep (1); print time; print "<br>"; }
      Interestingly enough, while it doesn't work with curl/wget, it DOES stagger the download/display within firefox. So I guess the code is as good as it can get, and it's just up to the browser god on who interprets what?