Post your Questions, Observations, Comments, Ideas and receive feedback from members. Listen to the "wisdom of the crowd"

Author Topic: Getting number of user online and other functionalities  (Read 1808 times)

osofem

  • Guest
Getting number of user online and other functionalities
« on: April 29, 2013, 10:04:11 AM »
Introduction
Knowing your website statistic is a very important factor in tracking the growth of your site. A more obvious use of such statistical information in is Forums, Communities and Social Networks where it is of paramount necessity to know

  • If a user is online (useful in Live Web chat)
  • The number of users currently online
  • The highest online ever (with date and time)
  • The number of users that has been online for that day
  • The time and date a user was Last Seen


This article presence how these can be achieved using PHP and MySQL. Implementing this using PHP and MySQL is pretty easy and straight forward (trust me on this  ;). You can grab the source files attached to this article which contains two files checker.php (the backend code) and check.php (which contains HTML, PHP, and AJAX to asynchronously ping the server for checker.php).
Test this on various browsers and tabs to simulate multiple users. Close few tabs and browser to see the effect

The Setup
A database online_users is needed on your MySQL server. Two tables are needed in this database; online and highest. The table online should contain two columns; column "id" which could be an INT or VARCHAR depending on the way the ID’s of users are handled on your site but for the purpose of this illustration, it will be VARCHAR(10). The second column in table online should be "time" which should be a TIMESTAMP.
The second table “highest” should contain two columns; column “time” which is a TIMESTAMP that defaults to the current time on the server and column “num” which is an INT.
You can set these up manually using your phpMyAdmin or by using the code below assuming your database name is “online_user” and you have connected to the MySQL server using the variable $connection.

<?php
.
.
.
//already connected to MySQL using $connection
//To create database
$sql = "CREATE DATABASE online_users";
mysql_query($sql, $connection);
 
//To create tables
$sql = "CREATE TABLE online_users.online (id VARCHAR( 10 ) NOT NULL , time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE = InnoDB";
mysql_query($sql, $connection);
 
$sql = "CREATE TABLE online_users.highest (time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , num INT NOT NULL ) ENGINE = InnoDB";
mysql_query($sql, $connection);
.
.
.
?>

PLEASE note that you have to create these database and tables before the source files included with this article can work. This section of database and table creation were left out of the source code so as to keep it clean, clear and straight to the point.

The checking checker
The "checker.php" contains the backend code but before usage you have to change the $db_host, $db_username, $db_password, $db_name variables to your MySQL host, username, password, and database name respectively.

Challenge 1:
The first step in achieving our aim is in logging the ID and current time of every user present on the site into the "online" table of the database and to ensure this information is updated as long as the user still have the site opened in their browser. If this is achieved, the following problems are solved at once.

Solution 1:
Get if a user is online: By checking the time the row of a user was last updated, you can tell if the user is still online or not. For instance, if you set the row to be updated every 30seconds and the last time the row was updated was 1 minutes or greater ago, you can rightly say the user is no longer online.
Get the number of users that are online: If you choose that a user can be considered offline if the time the row was last updated is 1 minutes or greater, then by getting the number of rows updated less than 1 minutes ago, you get the number of users online.
Last Seen: By checking the last time the row of a user was last updated, you can determine if he is online or the "Last Seen" time.
Number of users online today: By getting the number of rows that has been updated that particular day, you get the number that has been online that day.

Challenge 2:
The second challenge (and last since Solution 1 solved 4 of 5) is how to get the highest online ever. Of course this will be at a "point in time". This might look scary at first when you think a script might have to keep running on your server at all time so as to get the online of user online every milliseconds. That is not the solution anyway so relax!

Solution 2:[/b]
Highest Online Ever: to have highest online, you have to have users present online! This might first seem like a dump statement but it is true. So why not put the responsibility of checking for the "highest online ever" on online users instead of having Cron Jobs run a script perpetually on your server. If there are no users online then there is no need checking of highest online.
When a user reports his presence, the number of online users is checked and compared with the column "num" of the table "highest". If the number is greater or equals to "num", the current time and number is INSERT INTO or UPDATEd into the table.

The pinging check[/b]
The "check.php" file contains php codes, AJAX scripts and HTML that runs on the frontend. This is just like your web page i.e. what the user will see. AJAX is used to asynchronously communicate with the server every 30 seconds to report the presence of the user amidst others.

Codes and Explanation
Four out of our five challenges can be solved by the page simply reporting it presence to the server say every 30 seconds and the server appropriately updating the row in the table "online".

  • Reporting User’s Presence
<?php
.
.
//Report your presence
   if(isset($_GET[report]))
   {
      $query = "SELECT * FROM &quot;. $db_name .&quot;.online WHERE id = '%s' ";
      $query = sprintf($query, mysql_real_escape_string(stripslashes($_GET[id])));
      if(mysql_num_rows(mysql_query($query, $con)) > 0)
      {
         $query = "UPDATE ". $db_name . ".online SET time = '%s' WHERE id = '%s' ";
         $now = date('Y-m-d H:i:s', strtotime('now'));
         $query = sprintf($query, $now, mysql_real_escape_string(stripslashes($_GET[id])));
         mysql_query($query, $con);
      }
      else
      {
         $query = "INSERT INTO ". $db_name . ".online (id, time) VALUES ('%s', '%s')";
         $now = date('Y-m-d H:i:s', strtotime('now'));
         $query = sprintf($query, mysql_real_escape_string(stripslashes($_GET[id])), $now);
         mysql_query($query, $con);
      }
      //Set highest online info
      setHighestOnline($con, $db_name);
   }
.
.
.
?>

This piece of code sits on the backend (checker.php) and checks if $_GET[report] isset(). If true, that indicate a page is reporting the presence of a user. The code then check if the user has been registered into the table "online" before, if true (i.e. the number of row returned in the query is greater than zero) the row is UPDATEd else the information is INSERT INTO the table.
Remember in Solution 2 it was stated that whenever a user presence is reported, the number of online users should be checked and appropriately handled, that is the reason for the setHighestOnline() function. The function will be discussed later.
The user report it presence from check.php with this piece of AJAX

.
.
.
function doReport()
{
k = getXMLHttpRequestObject();
    if(k != false)
    {
        url = "checker.php?report&id=" + document.getElementById('userID').value;
        k.open("POST", url, true);
        k.onreadystatechange=function()
        {
            if(k.readyState==4)
            {
                //...Do nothing...
            }
        }                                       
        k.send();
    }
    else
    {
        alert("Cant create XMLHttpRequest");
    }
}
.
.
.
doReport();
setInterval(doReport, 30000);// Report user presence every 30sec
.
.
.

This is just a simple AJAX code but notice that “POST” was used in the open method but the parameters were passed using GET method (i.e. appending the parameters to the URL). $_GET[] was also used on the backend code. The purpose of using POST in the open method is to prevent caching, GET will always cache if used in the open method and this is not desirable in this situation hence the POST. All the other AJAX codes simply follow this pattern.
The parameter id in the variable url above should be the UserID of the user. In this example, an id is randomly generated and stored in a hidden input field.

.
.
.
<?php
     echo "<input type=hidden id=userID value=" . rand(0, 5) . ">";
?>
.
.
.
 
In your own code use the real UserID.

  • Setting the highest online ever

.
.
.
//Set the highest online at all time
   $highest_online = 0;
   function setHighestOnline($con, $db_name)
   {
      //Get number of user currently online
      mysql_select_db($db_name, $con);
      $query = "SELECT * FROM " . $db_name . ".online";
      $result = mysql_query($query, $con);

      if(mysql_num_rows($result) > 0)
      {
         while($row = mysql_fetch_assoc($result))
         {   //If last seen is less than 1 minute, user is assumed online
            if(abs((strtotime($row['time'])-strtotime(date('Y-m-d H:i:s', strtotime("now"))))) < 60)
            {
               $highest_online++;
            }
         }
      }
      
      //Get highest online previous record
      $query = "SELECT * FROM " . $db_name . ".highest";
      $result = mysql_query($query, $con);
      if(mysql_num_rows($result) > 0)
      {
         $row = mysql_fetch_assoc($result);
         if($highest_online >= $row['num'])
         {
            //The currently online is greater than or equals to the previous record so update
            $query = "UPDATE ". $db_name .".highest SET time = NOW(), num = '" . $highest_online . "'";
            mysql_query($query, $con);
         }
      }
      else
      {
         //Highest online never set before so set the record
         $query = "INSERT INTO ". $db_name .".highest(time, num) VALUES(NOW(), '" . $highest_online . "')";
         mysql_query($query, $con);
      }
   }
.
.
.

This will simply check for the number of users online from table “online” and compare the result with the record in table “highest”. Table “highest” is UPDATEd or INSERT INTO appropriately.
The other function just follows this pattern of checking, updating, and inserting into the MySQL database and are pretty simple to comprehend. The setInterval() function in the javascript is used to run all the AJAX functions at specified interval

.
.
.
setInterval(doReport, 30000);// Report user presence every 30sec
setInterval(numOnline, 60000);//Get number of user online every 60sec
setInterval(lastSeen, 60000);//Get the last seen time of a user every 60sec
setInterval(highestOnlineEver,(60000*5));//Get the highest online every 5 minutes
.
.
.
 

Other necessities
  • Ensure both “checker.php” and “check.php” are in the same directory, else you will have to update the url variable in the AJAX code appropriately
  • Note that the code assumes your connection to the database will never fail so no error handling was built in
  • You can also extend the code to include a function too get the current page the user was viewing at a particular time. This and others were not included so as to keep the code focused, short, and clear. Though this can be featured as a Part Two on popular demand[\li]

    1st Revision: 9th of April, 2013
    The basic algorithm still remains but the original code was altered a little to carter for some oversight

    • The Daylight Time Saving behavior of strtotime() of PHP: The +1 hour advance of time by strtotime() of PHP during DTS was not considered in the initial code. This led to the inability of the code to detect online users during DTS because all user online appear to have been offline for the past one hour. That was fixed by passing date('Y-m-d H:i:s', strtotime('now')) as the current time instead of using MySQL NOW()
    • An unexpected behavior was also detected whereby function setHighestOnline() was returning MySQL error "No Database selected". That was also fixed by passing an already connected MySQL link to the function.
    • and some typo's
« Last Edit: May 03, 2013, 09:27:38 AM by osofem »



Nigeria Oil & Gas Forum

Getting number of user online and other functionalities
« on: April 29, 2013, 10:04:11 AM »

 

Related Topics

  Subject / Started by Replies Last post
0 Replies
1435 Views
Last post September 12, 2013, 05:20:38 PM
by Temmy
0 Replies
1027 Views
Last post October 01, 2014, 10:00:39 AM
by rednet
0 Replies
420 Views
Last post December 05, 2014, 04:53:07 AM
by semiop
0 Replies
697 Views
Last post March 07, 2015, 10:20:32 PM
by aishabamba
0 Replies
275 Views
Last post August 25, 2016, 09:15:25 AM
by pintogen

Sponsored Ads

Quick Links

About Us
Contact us
Register
Privacy Policy

Contact Info

Nigeria Oil & Gas Forum

Email Address
info@oilandgasforum.com.ng
Contact Form
Business Hours
9.00am - 5.00pm (Mon - Sat)

Would you like to partner with us on this forum?

Then you can contact us here


Nairaland     Oil Prices     UK Gas Forum     Ghana Gas Forum     Russian Oil & Gas Forum     Israel Oil Forum     Agric Forum      freeslots.la

Powered by EzPortal