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
);