Check User Online or Offline on Laravel [100% Working]


Laravel

Author: Steve Alila
Reviewer: Deepak Prasad

Detecting if a user is online or offline can be useful for a variety of reasons in web applications. For example, it can help you to provide real-time features such as chat or notifications, or to track user activity for analytics purposes. There are several methods you can use to detect a user's online status:

  1. Session tracking: One common approach is to use server-side session tracking to determine when a user was last active. This can be done by setting a timestamp in the user's session data whenever they perform an action on the site, such as loading a page or submitting a form. You can then compare this timestamp to the current time to determine if the user is currently online or offline.
  2. Heartbeat monitoring: Another approach is to use client-side heartbeat monitoring to detect when a user is active on the site. This involves periodically sending a small request to the server (known as a "heartbeat") to indicate that the user is still active. You can then use the frequency of these requests to determine if the user is online or offline.
  3. WebSocket connections: If you need real-time updates, you can use WebSocket connections to establish a persistent connection between the client and the server. This allows the server to push updates to the client in real-time, without the need for periodic polling.
  4. IP address tracking: Another method is to track the user's IP address and assume that they are online as long as their IP address remains connected to the server. However, this approach can be less accurate, as a user's IP address may remain connected even if they are not actively using the site.

These are just a few examples of the methods you can use to detect a user's online status. The best approach will depend on your specific use case and the requirements of your application.

 

Here is a screenshot which shows the status of the user online or offline on Laravel, let's explore how this can be achieved using Session Tracking.

Check User Online or Offline on Laravel [100% Working]

It is simple. Follow these straightforward steps to achieve the effect.

 

Step-1: Install a new Laravel app

laravel new user_online
cd user_online

We install a new Laravel 10 app called user_online and cd into the new project directory.

 

Step-2: Generate Auth scaffolding

composer require laravel/breeze --dev
php artisan breeze:install

The Breeze package simplifies Laravel authentication. You don't have to create user registration and authentication from scratch. Besides, it is comes with Tailwind CSS and Alpine.js configuration.

 

Step-3: Track the status in the database

Create database with the name specified in the .env file.

mysql -u root -p
mysql> create database user_online;
mysql> exit;

Next, insert a last_seen record in the database.

// in <date>_000000_create_users_table

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->timestamp('last_seen')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('users');
    }
};

Migrate the changes.

php artisan migrate

 

Step-4: Create and configure status middleware

A status middleware is a piece of code that can be used to determine if a user is online or offline in a web application. To create a status middleware in Laravel, you can use the php artisan make:middleware command to generate a new middleware class. In this class, you can add logic to update the user's last activity timestamp and check if the user is online or offline. To use the middleware, you can add it to the appropriate route or group of routes in your web.php file. This will ensure that the middleware is run on every request to that route or group of routes, allowing you to track the user's online status in real-time

php artisan make:middleware UserActivity

Check User Online or Offline on Laravel [100% Working]

Now tell the middleware app/Http/Middle/UserActivity file how to handle the status of the user online or offline on Laravel.

<?php

namespace App\Http\Middleware;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Carbon\Carbon;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class UserActivity
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        if (Auth::check()) {
            $expires_after = Carbon::now()->addSeconds(5); 
            Cache::put('user-online' . Auth::user()->id, true, $expires_after);
        }
        return $next($request);
    }
}

Using the Carbon class, we track the amount of time that has elapsed. We use the class to persist the user's online online status even after they have logged out of the dashboard.

Lastly, register the new middleware in the app/Http/Kernel.php file.

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    /**
     * The application's global HTTP middleware stack.
     *
     * These middleware are run during every request to your application.
     *
     * @var array<int, class-string|string>
     */
    protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array<string, array<int, class-string|string>>
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\UserActivity::class,
        ],

        'api' => [
            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            \Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    /**
     * The application's middleware aliases.
     *
     * Aliases may be used to conveniently assign middleware to routes and groups.
     *
     * @var array<string, class-string|string>
     */
    protected $middlewareAliases = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \App\Http\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    ];
}

Check User Online or Offline on Laravel [100% Working]

 

Step-5: Write the controller

Make the controller.

php artisan make:controller UserController

Then, tell the controller file how to handle user online or offline on Laravel whenever user status is requested.

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Support\Facades\Cache;

class UserController extends Controller
{
    public function userOnlineStatus()
    {
        $users = User::all();
        foreach ($users as $user) {
            if (Cache::has('user-online' . $user->id))
                echo $user->name . " is online. <br>";
            else
                echo $user->name . " is offline <br>";
        }
    }
}

Now make the controller accessible through the routes/web.php file.

<?php

use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

Route::get('/', function () {
    return view('welcome');
});

Route::get('status', [UserController::class, 'userOnlineStatus']);

Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');

Route::middleware('auth')->group(function () {
    Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
    Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
    Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});

require __DIR__.'/auth.php';

The userOnlineStatus function in the UserController will be invoked on hitting the status route.

 

Step-6: Create a view

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <!-- Fonts -->
        <link rel="preconnect" href="https://fonts.bunny.net">
        <link href="https://fonts.bunny.net/css?family=figtree:400,600&display=swap" rel="stylesheet" />

        <!-- Styles -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])
    </head>
    <body class="antialiased">
        <div class="relative sm:flex sm:justify-center sm:items-center min-h-screen bg-dots-darker bg-center bg-gray-100 dark:bg-dots-lighter dark:bg-gray-900 selection:bg-red-500 selection:text-white">
            @if (Route::has('login'))
                <div class="sm:fixed sm:top-0 sm:right-0 p-6 text-right">
                    @auth
                        <a href="{{ url('/dashboard') }}" class="font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500">Dashboard</a>
                    @else
                        <a href="{{ route('login') }}" class="font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500">Log in</a>

                        @if (Route::has('register'))
                            <a href="{{ route('register') }}" class="ml-4 font-semibold text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white focus:outline focus:outline-2 focus:rounded-sm focus:outline-red-500">Register</a>
                        @endif
                    @endauth
                </div>
            @endif

            <div class="w-4/5 mx-auto my-4 sm:w-1/2">
                <h2 class="text-2xl semi-bold mb-10 text-center">All Users</h2>

                @php $users = DB::table('users')->get(); @endphp
                <table class="border-1 shadow-xl w-full">
                    <tr class="bg-gray-300">
                        <th class="py-2 text-center">Name</th>
                        <th class="py-2 text-center">Email</th>
                        <th class="py-2 text-center">Status</th>

                    </tr>
                    @foreach($users as $user)
                        <tr>
                            <td class="py-2 text-center">{{$user->name}}</td>
                            <td class="py-2 text-center">{{$user->email}}</td>
                            <td class="py-2 text-center">
                                @if(Cache::has('user-online' . $user->id))
                                    <span class="text-green-500">Online</span>
                                @else
                                    <span class="text-gray-500">Offline</span>
                                @endif
                            </td>

                        </tr>
                    @endforeach
                </table>

            </div>

        </div>
    </body>
</html>

We loop through all the users and display them with their online or offline statuses on a table.

 

Step-7: Start development servers

frontend

npm install
npm run dev

We install frontend assets that came with Breeze and then start the dev server.

backend

php artisan serve

Similarly, we start the Laravel dev server, accessible via http://127.0.0.1:8000.

user online or offline on Laravel

 

Now an logged in user has an online status, whereas a logged out user has an offline status.

Check User Online or Offline on Laravel [100% Working]

 

Likewise, the status route reveals all users with online or offline status message.

Check User Online or Offline on Laravel [100% Working]

 

Conclusion

In seven steps, you have successfully created and configured an app to handle user online or offline on Laravel. You:

  1. installed a new Laravel app and scaffolded the auth with Laravel Breeze.
  2. created a database and inserted user (online or offline) status record into it. You then made the auth middleware before configuring and registering it.
  3. created the views file to see a table of online and offline users.

Session tracking is a common approach to detect if a user is online or offline in web applications. To implement this approach, you can use server-side session data to store the user's last activity timestamp. When a user logs in, you can store their current timestamp in their session data. Then, create a middleware to update the user's last activity timestamp on every request. Use the last activity timestamp to determine if the user is online or offline. For example, you can create a helper function that checks if the user's last activity timestamp is less than a certain amount of time old. If it is, the function returns true to indicate that the user is online. Otherwise, the function returns false to indicate that the user is offline. You can then use this helper function in your views or controllers to display the user's online status.

Overall, session tracking is a simple and effective way to implement user online/offline detection in web applications. However, keep in mind that this approach requires server-side session data and may not be suitable for applications that require real-time updates or high-precision tracking of user activity. If real-time updates are needed, other methods such as WebSocket connections or client-side heartbeat monitoring may be more suitable.

 

Steve Alila

Steve Alila

He specializes in web design, WordPress development, and data analysis, with proficiency in Python, JavaScript, and data extraction tools. Additionally, he excels in web API development, AI integration, and data presentation using Matplotlib and Plotly. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

1 thought on “Check User Online or Offline on Laravel [100% Working]”

  1. This is cool, but it would probably make more sense to create a row in the users table ‘last_active’ and store a dateTime in there, that way you can also know when they were last active (for marketing purposes for example)

    Reply

Leave a Comment