在論壇裡有人問我如何統計在線人數?我也不知道什麼是最好的方法。下面是本站的實現的原理,我把它寫出來,供大家參考。這只是我的方法,肯定不是最好的,還希望高手們予以指正。
其實,要真正統計同時在並發在線的人數,是一件不太現實的事,這是因為HTTP協議是種無狀態的協議。當客戶端向服務器發出一個請求時,服務器會馬上建立一個新的TCP/IP連接,在該會話結束後,如頁面完全載入後,這個連接就關閉了。一般來說,在線人數指的定是在一定時間段內同時訪問站點的人數,而不是基於HTTP協議的並發連接數。
讓我們先來看看一個訪客是如何訪問一個網站的。他在浏覽器的地址欄裡輸入了目標網站的地址,然後在一段時間內持續浏覽該網站的網頁,最後,關閉浏覽器或輸入新的網址——浏覽結束了。對於服務器端來說,訪客到來是可以知道的,訪客在浏覽頁面也是可以知道的,可是怎麼知道什麼時候走的呢?由於HTTP協議是無狀態的,所以無法知道。通常的做法是記下訪客最後一次浏覽站點頁面的時間。如果該訪客在一個特定的時間內沒有新的動作,那麼可以認為他走了。
根據上面的這個思路,我覺得最好用數據庫,因為數據庫要比其他方法如文本文件的效率要高。下面的例子是使用MySQL的,很容易使用其他類型的數據庫系統。然後,在所有的頁面中調用這個PHP文件,一方面更新數據,另一方面可以顯示在線的人數。但是,有一個問題--到底在多長時間內訪問的人算是並發的呢?一般來說,是半個小時,也就是1800秒,具體的要根據網站的情況來確定。這個時間越長,統計出的並發在線的人數就越多。本站的是15分鐘,900秒。用訪問者的IP地址表示一個訪問者是個不錯的方法。在撥號上網的情況下,被分配了相同IP地址的兩個用戶在短時間內浏覽同一個網站的概率是很小的。
首先,用MySQL的工具建一個表:
CREATE TABLE ccol(
id integer not null auto_increment, #記錄的ID
ip char(15) not null, #訪問者的IP地址
dtstamp datetime not null, #最後訪問時間
uri char(255), #訪問者請求的URI
primary key (id)
);
然後,寫一段PHP代碼:
/*
文件:ccol.php - ConCurrent OnLine statistics
目的:統計同時在線浏覽的人數
作者:Hunte, [email protected]
修改:2000-4-25
*/
$duration=1800;
require "db.php";
//包含DBSQL,詳情可以參考我的另一篇文章
$ccol=new dbSQL;
$ccol->connect();
$ccol->query("DELETE FROM ccol WHERE (UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(dtstamp))>$duration");
//刪除超過半小時的記錄
$ccol->query("SELECT * FROM ccol WHERE ip=$REMOTE_ADDR");
//判斷當前的IP是否在該表中存在
if ($ccol->nf())//有?
{
$ccol->next_record();//下移找到的記錄數組的指針
$id=$ccol->f(id);
$ccol->query("UPDATE ccol SET dtstamp=now(), uri=$REQUEST_URI WHERE id=$id");
//設置最後訪問時間和訪問頁面
}
else//沒有
{
$ccol->query("INSERT INTO ccol VALUES (0, $REMOTE_ADDR, now(), $REQUEST_URI)");
}
$ccol->query("SELECT COUNT(*) AS ccol FROM ccol WHERE (UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(dtstamp))<=$duration");
//找出在半個小時內的記錄,後面的WHERE子句可有可無--超出時間的已經被刪除了
$ccol->next_record()
echo "在線人數:", $ccol->f(ccol);
$ccol->free_result();
?>
怎麼用呢?在站點的每個頁面的上面調用這個程序,舉例來說:
--index.php
...