07-05-2001
by John Saya
Did you ever want to output information in realtime, such as making
a chat room, or displaying data as the server processes it -- like
credit cards, searching, or? Well, with most web servers it is
possible, and relatively simple to do using Perl. It's called
server pushing or streaming.
It's all done by sending the
multipart/mixed header instead of
using the standard
text/html header when sending text from your
Perl script. The
text/html header generally only displays information when all
of the data is sent from the server, and the server closes the connection
with the browser. The
multipart/mixed keeps a live connection open
with the server and displays all data on the visitor's browser as it is
output by the server. However, be careful when doing this as you could
cause your server to become extremely slow or crash due to low memory or
system resources.
The first thing you should know is that many Windows based web servers
do not support this header, so it will act the same as
text/html.
But, give it a shot any way, because by the time you read this, your web
server may support it.
The next step is crucial in having a realtime stream. It's called buffering.
Basically Perl will buffer all data until the buffer is full, before any data
is actually sent to tge browser. So, you turn off buffering in your script
by using:
$| = 1;
Another thing to keep in mind is that Microsoft Internet Explorer and
Netscape Communicator require slightly different methods of accomplishing a
realtime data stream. So, we will add a browser check routine and call it
in the beginning of the script:
sub check_browser
{
$browser = 0; #MSIE / AOL
if ($ENV{'HTTP_USER_AGENT'} =~ /Mozilla/i)
{
if ($ENV{'HTTP_USER_AGENT'} !~ /MSIE/i and $ENV{'HTTP_USER_AGENT'} !~ /opera/i)
{
$browser = 1; #Netscape
}
}
}
To call the above routine, just use:
&check_browser;
Now when you want to output, first use this:
print "Content-type: multipart/mixed;boundary=\"boundary\"\n\n";
if ($browser == 1)
{
print "\n--boundary\n";
print "Content-type: text/html\n\n";
}
The boundary portion really doesn't apply to this process, but I use
it anyway for older browser compatibility. Remember that you only
need to send the above header one time in your script. Once it's
sent, a live connection is open between the server and the browser until
the script exits or the visitor closes their browser.
The next step is optional, but you may want to output a few lines of hidden
comments to ensure the browser is beginning the stream. Some browsers buffer
their own data and won't stream until that buffer is full:
for ($x = 0; $x < 50; $x++)
{
print "<!-- FORCE STREAM -->\n";
}
Now you can output text in realtime. For testing purposes, you can
display ten lines of text in one second intervals:
for ($x = 0; $x < 10; $x++)
{
print "Line $x<BR>\n";
sleep 1;
}
Be sure to use the newline character (\n) because some Netscape browsers
will not output the text until the newline is detected.
Your entire Perl script should look like this:
#!/usr/bin/perl
$| = 1;
&check_browser;
print "Content-type: multipart/mixed;boundary=\"boundary\"\n\n";
if ($browser == 1)
{
print "\n--boundary\n";
print "Content-type: text/html\n\n";
}
for ($x = 0; $x < 50; $x++)
{
print "<!-- FORCE STREAM -->\n";
}
for ($x = 0; $x < 10; $x++)
{
print "Line $x<BR>\n";
sleep 1;
}
exit;
sub check_browser
{
$browser = 0; #MSIE / AOL
if ($ENV{'HTTP_USER_AGENT'} =~ /Mozilla/i)
{
if ($ENV{'HTTP_USER_AGENT'} !~ /MSIE/i and $ENV{'HTTP_USER_AGENT'} !~ /opera/i)
{
$browser = 1; #Netscape
}
}
}
You should now have a basic understanding of how to stream data in realtime
to a visitor's browser. If you want to see a more sophisticated method of
streaming, check out WebChatter at the
CGI Connection. Happy streaming!
[ Back ] [ Main Menu ]
Download Fuse Node.js Compiler