Jump to content

[SOLVED] PHP session or mysql users online count and users viewing page list


GregL83

Recommended Posts

I know there are tutorials out there and I have read some, but I am having trouble figuring out which direction to go.  I want to track users and guests.  I need to display the number of users online and the number of guests online.  Also, some pages will show which users and how many guests are viewing the current pages.  PHPfreaks uses this tech.

 

I have found tutorials that do this using a mysql database and timeouts.  I have also seen this done using sessions variables and session_save_path().  Session save path can tell when a user closes connections to the website and is apparently faster than connecting to the database, but setting the timeout of session variables can destroy other important session variables.  Using the mysql method has issues as well.  The accuracy is dependent on the timeout value.  If too long, then some users could have left your site 30 minutes ago but will still appear as an online user viewing a page.  Also,  if too short the user may still be reading a page or browsing a page but will be reported as offline after the session timeouts.

 

Which is the best way to do this?  A combination?  I want this information to be accurate.  Are there any tutorials I might have missed?

Link to comment
Share on other sites

The best way is to use AJAX to "ping" a web page that keeps updating the last access time in a database table. By doing this you can shorten the timeout. If you "ping" at 1 minute intervals, you can use a 2 minute timeout (the timeout is twice the period of the update to insure update is not missed.) If you pass a GET parameter on the end of the request that AJAX makes to indicate what the current page is, you can use one piece of code to do the updating for all the pages.

 

As you discovered, altering the operation of the session garbage collection renders the session unusable for any other purpose.

Link to comment
Share on other sites

Cool.  What do you mean by "ping web page"?  Are you having a javascript ajax call ran every 2 minutes?  A quick sample of the javascript timing function would be awesome... I started using jquery for my ajax calls.

 

Also, what about server loads?  Ajax runs slowly sometimes.  I get the basic concept, but I am not sure what you mean by "ping."

Link to comment
Share on other sites

Here is the basic demo code to do this. Must be modified to meet your needs, for example a random user is generated, whereas you would need to use the actual user information  -

 

Main page -

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head>
<title>Ajax Keepalive demo</title>
<script type="text/javascript">
/* Page that uses an AJAX request to "ping" a page on the server to indicate a page from this site is still being displayed in the browser.
Passes a parameter on the end of the url that could be used, for example, to log which page a visitor is on.
This example pings/requests the page - keepalive2.php */
var page_to_request = 'keepalive2.php';

/* The page_to_request returns a text response that is displayed in the tag with the id in response_id */
/* In this example code, this text response will be the number of members online */
var response_id = 'response';

/* This page shows a count in c to indicate it is doing something */
var c=0;
var t;
function startTime()
{
document.getElementById('counterdisplay').innerHTML=c; // display activity count
c=c+1; // increment activity count to show page is doing somtheing
t=setTimeout('startTime()',30000); // how often to ping the server (30000 = 30 seconds)
ajaxkeepalive('abc123'); // pass a string (this page name...) to the server as part of the AJAX http request
}
</script>
<script type="text/javascript" src="ajaxkeepalive.js"></script> 
</head>
<body onload="startTime()">
<p><span id="counterdisplay"></span></p>
<p>Members online: <span id="response"></span></p>
</body>
</html>

 

External javascript file (ajaxkeepalive.js in the main code) that performs the AJAX request -

var xmlHttp

function ajaxkeepalive(str)
{
xmlHttp=GetXmlHttpObject()
if (xmlHttp==null)
{
	alert ("Browser does not support HTTP Request")
	return
} 
var url=page_to_request
url=url+"?q="+str
url=url+"&sid="+Math.random()
xmlHttp.onreadystatechange=stateChanged 
xmlHttp.open("GET",url,true)
xmlHttp.send(null)
} 

function stateChanged() 
{ 
if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete")
{ 
	document.getElementById(response_id).innerHTML=xmlHttp.responseText 
} 
} 

function GetXmlHttpObject()
{ 
var objXMLHttp=null
if (window.XMLHttpRequest)
{
	objXMLHttp=new XMLHttpRequest()
}
else if (window.ActiveXObject)
{
	objXMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
}
return objXMLHttp
}

 

Auxiliary page that is requested by AJAX (keepalive2.php in the above code) -

<?php
// page that is pinged by AJAX request
// updates the user id and date/time in the "online" database table
// returns the number of users online (and for demo purposes returns the string parameter ?q= that was passed on the end of the url in the http request)

include $_SERVER['DOCUMENT_ROOT'] . "/logoninfo.php"; //get database login values
$link = mysql_connect($dbhost, $dbuser, $dbpwd) or die('Could not connect: ' . mysql_error());
mysql_select_db($dbname, $link) or die('Could not select database: ' . mysql_error());

// INSERT/UPDATE -
// The following two lines are for demo purposes (generates a random user id).
// In real life this would be the currently logged in user id from a session...
$max = 10;
$id = rand(1,$max);

$query = "INSERT INTO online
    SET id = $id
    ON DUPLICATE KEY UPDATE
ts = NULL"; // must have an UPDATE expression here. NULL value is needed to cause TIMESTAMP type column to update
mysql_query($query) or die("Query failed: $query<br />Mysql error: " . mysql_error());

$limit = 60; // if last access is less than this number of seconds ago, consider an id to be online

// DELETE the old records  (only if you are finding how many or who is online) -
$query = "DELETE FROM online WHERE ts < DATE_SUB(NOW(),INTERVAL $limit SECOND)";
mysql_query($query) or die("Query failed: $query<br />Mysql error: " . mysql_error());

// get and display the count of the remaining rows
$query = "SELECT count(*) as online FROM online"; // get a count of how many are online
$result = mysql_query($query) or die("Query failed: $query<br />Mysql error: " . mysql_error());
$row = mysql_fetch_assoc($result);
echo "(Page:{$_GET['q']}) {$row['online']}"; // for demo purposes pass the ?q= parameter from the end of the http request back to the page
?>

Link to comment
Share on other sites

nice. nice. nice.  thats what I was thinking you meant....

 

I appreciate all the code.  After all my searching I hope other people will stumble upon this thread.

 

Any idea on the server load?  Is this how phpfreaks does this?

 

Once again, thank you.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.