Membuat last user online dengan PHP dan Javascript berbasis file Log

Membuat user online dengan Server Sent Events

RyanID - Untuk membuat sebuah data analisis mengetahui jumlah pengguna online kita bisanya bisa menggunakan metode last_online, yakni sebuah kolom pada database mysql yang di isi dengan jenis data TIMESTAMPP.

Kemudian untuk menghitung jumlah user online kita bisa menggunakan sebuah query seperti di bawah ini. Query ini akan mengambil data mysql yang tidak lebih dari 3 detik yang lalu.

SELECT COUNT(*) as total FROM `user` WHERE last_online BETWEEN (NOW() - INTERVAL 3 SECOND) AND NOW();

Lalu untuk proses pengiriman data secara terus menerus pada sisi front end kita bisa menggunakan metode SSE, Server-Sent Events (SSE) adalah teknologi yang digunakan untuk mengirimkan data dari server ke client secara real-time. SSE merupakan bagian dari HTML5 yang memungkinkan client untuk membuka koneksi ke server dan menerima data secara terus-menerus tanpa perlu meminta data tersebut secara berkala.

Tapi kali ini kita hanya akan membuat user online menggunakan sebuah file log saja. Untuk membuatnya, pertama persiapkan sebuah file dengan nama user-online.php, dan isi kode nya dengan kode berikut ini.

<?php

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

$log = "user_online.json";
if (!file_exists($log)){ file_put_contents($log, json_encode(array())); }
$dax = @file_get_contents($log);
$data = json_decode($dax, true);
$client_ip = ip2p();

$new_data = [];
if (!$_COOKIE['user_online']){
$time = time();
$data[] = array("time" => $time, "agent" => $_SERVER['HTTP_USER_AGENT'], "ip" => $client_ip);
$data = json_encode($data, JSON_PRETTY_PRINT);
file_put_contents($log, $data);
setcookie('user_online', "1", time() + 30);
}


$data = json_decode(@file_get_contents($log), true);
foreach ($data as $item) {
// mengambil data time dari setiap elemen array
 $time = $item['time'];
 $agent = $item['agent'];
// menghitung selisih waktu sekarang dengan data time
// jika selisih waktu kurang dari 30 detik, pertahanin
if ( (time() - $time)  < 30) {
$online[]=1;
$new_data[] = $item;
}
}
file_put_contents($log, json_encode($new_data, JSON_PRETTY_PRINT));

$data = array("data" => count($new_data));
    echo "data: ".json_encode($data) . PHP_EOL;
    echo PHP_EOL;
    ob_flush();
    flush();

function ip2p()
{
    
    if (!isset($ip)) {
        if (!empty($_SERVER["HTTP_CF_CONNECTING_IP"])) {
            $ip = $_SERVER["HTTP_CF_CONNECTING_IP"];
        } elseif (!empty($_SERVER["HTTP_FASTLY_CLIENT_IP"])) {
            $ip = $_SERVER["HTTP_FASTLY_CLIENT_IP"];
        } elseif (!empty($_SERVER["HTTP_CLIENT_IP"])) {
            $ip = $_SERVER["HTTP_CLIENT_IP"];
        } else {
            $ip = $_SERVER["REMOTE_ADDR"];
        }
    }
    return $ip;
}


?>

Karena user nya bersifat anonim tidak ada databas ekhusus yang menangani user, kita coba menggunakan cookies browser dengan waktu simpan selama 30 detik. Di sini kita menggunakan sebuah perkondisian, dimana jika cookies tidak terdeteksi maka data user akan di simpan ke dalam sebuah file user-online.json

user-online.json ini adalah database array yang berisi array key berupa timestampp, agent, dan ip pengguna. Nantinya semua data user online akan di tampung sementara dalam sebuah file json.

Kemudian langkah kedua, kita coba ambil kembali jumlah database user online yang tersimpan dalam file user-online.json, kemudian melakukan looping dengan sebuah kondisi jika waktu timestampp nya dikurangi dari waktu sekarang lebih dari 3 0 detik. artinya user tersebut merupakan user baru dan online.

Kemudian data user online ini kita tampung menjadi array dan di simpan ulang ke dalam sebuah database file user-online.json, kegiatan ini terjadi secara terus menerus tanpa henti.


Pada sisi client kita akan menggunakan SSE, bukan websocket karean websocket lebih ribet dalam proses configurasinya. Berikut ini adalah code untuk sisi client

<span id="pengguna_online">0</span>
<script>
 const serverHost = "user-online.php"
 const source = new EventSource(serverHost);
 source.onmessage = function(event) {
       kelolah(event);
      };

 source.onclose = function() {
  console.log("Koneksi terputus, mencoba menghubungkan ulang .");
  eventSource = new EventSource(serverHost);
  eventSource.onmessage = function(event) {
     kelolah(event);
     console.log("Pesan di terima..");
   };
};


function kelolah(msg){
   const data = JSON.parse(msg.data);
   document.getElementByid("pengguna_online").innerHTML(data.data);
}
</script>

Untuk menangani proses pengiriman data dari server, SSE di rancang untuk selalu terkoneksi ke server. Jadi apabila koneksi internet terputus, atau ada hal lain yang menyebabkan sebuah internet terputus maka sse akan mengkoneksikan diri nya ulang ke server.

Untuk segi akurasi koneksi menggunakan SSE akurat sekitar 2-3 detik, karena ada sedikit delay antara permintaan kedua pada server. Koneksi tidak terjadi secara terus menerus mengikuti waktu, tetapi terus menerus dengan beberapa jedah waktu.

Sistem ini saya aplikasikan pada aplikasi sederhana untuk melacak berapa banyak pengguna online. Anda bisa memodifikasi data dengan menambah data pelacakan jika ingin melihat lebih detail mengenai visitor manas aja yang online.

Silakan di kreasikan sendiri, ini hanya sebuah tips tentang membuat sistem user online yang dinamis menggunakan php dan javascript. Kita tidak menggunakan websocket, dengan alsan websocket lebih rumit ketika di konfigurasi di PHP.

Beberapa layanan Cpanel hosting mungkin tidak mendukung websocket, selain itu websocket juga membutuhkan ssl jika di akses via domain yang sudah mengggunakan SSL.

RyanID
RyanID Saya aslinya tertarik pada teknologi elekronika, tapi karena kurang di dukung ortu, akhirnya pindah ke coding. Saat ini bekerja sebagai fullstack dev di Netzku.com