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

Does anybody have (or know of) a Perl script to display users online on a Web site?
I've tried installing the one from http://www.perlonline.com/usersonline/index.htm, but can't seem to get it to work.
Also, rather than a big square box with a number in it, I really would prefer a simple text display. For example,

Users Online = 29


Many thanks in advance,

Replies are listed 'Best First'.
Re: Users Online script that works??
by merlyn (Sage) on Feb 05, 2005 at 19:38 UTC
    Since HTTP is a stateless protocol, the "users online" is a meaningless number, unless you defined it as "authenticated users active within the recent N minutes" or something like that. And once you get a definition, the implementation is straightforward, because the definition tells you what you have to look at and how to interpret the results.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      Wow! Thanks for the speedy reply Randal! :-)

      I *think* I understand what you're talking about, and the usersonline script
      that I mentioned above does have a default time of 15 minutes:
      #The number of minutes the user is assumed to be online after a hit. ( +default 15) $minutes = 15;
      However (for whatever the reasons), I'm unable to get the script to work...
      I do have SSI and have followed the install directions as faithfully as I know how (twice now!)
      anyhow...

      Thanks again Randal,
Re: Users Online script that works??
by saskaqueer (Friar) on Feb 05, 2005 at 19:58 UTC

    Here's one example of such an implementation. You could use this as a base to design something similar, or this by itself should work as a Server Side Include (SSI). Change the $min variable to the number of minutes that pass before a user is considered to have left the site. The MySQL database is probably a little bit overkill for such a small thing, but it works. Also, the cleanup to delete old entries would probably be better off as a cron job that executes once in a while instead of being done everytime the script is accessed. Also, the 'track id' generation could probably use an overhaul, but once again, it works.

    #!/usr/bin/perl -w $| = 1; use strict; use CGI; use DBI; use Time::Piece; my $min = 5; # number of minutes for timeout my $dbh = DBI->connect('dbi:mysql:db_name', 'usr', 'pwd', { RaiseError => 1, AutoCommit => 1 } ); my $q = CGI->new(); my $track_id = $q->cookie('trackid'); if ( defined($track_id) ) { $dbh->do( 'UPDATE trackids SET lastaccess=NOW() WHERE trackid=?', undef, $track_id ); print $q->header(); } else { $track_id = join( '', map { chr( int( rand(100) + 1 ) ) } 1..100 ); $dbh->do('INSERT INTO trackids VALUES(?, NOW())', undef, $track_id +); print $q->header( { cookie => $q->cookie( { name => 'trackid', value => $track_id } ) } ); } my $time = localtime(); $time -= 60 * $min; $time = $time->strftime("%Y-%m-%d %H:%M:%S"); $dbh->do( 'DELETE FROM trackids WHERE lastaccess < ?', undef, $time ); my $rec = $dbh->selectrow_arrayref( 'SELECT count(trackid) FROM trackids WHERE lastaccess > ?', undef, $time ); $rec = defined($rec) ? $rec->[0] : 0; print "$rec users online.\n"; __END__ the mysql database: CREATE TABLE trackids( trackid CHAR(100) NOT NULL, lastaccess DATETIME NOT NULL );
      Thanks! :-)

      Your script looks great - I'll see if I can get it to work!

      Thanks again,