Roy-Try-Catch
← Back to list

【Laravel】利用websocket取得在線人數

Roy • Updated 2026-10-15 15:38:43

更新提醒(2026-10):本文寫於 2021 年,使用 beyondcode/laravel-websockets、Laravel Mix(MIX_ 開頭的環境變數)與 pusher-php-server ^4.1。這些套件與前端建置方式可能已不適用於新版 Laravel(新版專案多半改用 Vite,官方也提供 Reverb),請自行確認各套件目前的維護狀態與相容版本。較新的作法可參考 【RealTime】Laravel Reverb - 官方 WebSocket Server 完整實作。

本篇介紹如何在 Laravel 框架中,利用 WebSocket 取得在線人數。

# 新增Project
laravel new {project}

修改 .env

# .env
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=online
PUSHER_APP_KEY=online
PUSHER_APP_SECRET=onlineonline

修改 bootstarp.js

# /resources/js/bootstarp.js
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
    broadcaster: 'pusher',
    encrypted: false,
    key: process.env.MIX_PUSHER_APP_KEY,
    cluster: process.env.MIX_PUSHER_APP_CLUSTER,
    wsHost: window.location.hostname,
    wsPort: 6001,
    forceTLS: false,
    disableStats: true
});

安裝套件

# cmd(安裝套件)
npm install
composer install
composer require pusher/pusher-php-server ^4.1
npm install --save laravel-echo pusher-js 
composer require beyondcode/laravel-websockets
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
php artisan migrate
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"

新增 Middleware

因為會用到 Presence 頻道,而它屬於私有頻道,必須經過授權才能連上。

於是我們建立一個 Guest 的 Middleware 來做認證。

namespace App\Http\Middleware;

use Closure;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class AuthenticateGuest
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        $fakeUser = new User();
        $fakeUser->virtual_client = true;
        $fakeUser->id = rand(100,1000);
        $fakeUser->name = Str::random('10');

        $request->merge(['user' => $fakeUser]);
        $request->setUserResolver(function () use ($fakeUser) {
            return $fakeUser;
        });
        return $next($request);
    }
}

修改 Provider

在這裡把 channel 的 middleware 設定成剛剛建立的 authenticate-guest。

# BroadcastServiceProvider
public function boot()
{
    Broadcast::routes(['middleware' => ['authenticate-guest']]);

    require base_path('routes/channels.php');
}

Kernel.php 也要記得註冊剛剛建立的 authenticate-guest:

# Kernel
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::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' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    'authenticate-guest' => \App\Http\Middleware\AuthenticateGuest::class,
];

啟動 WebSocket(預設連接埠:6001)

# 預設port:6001
php artisan websockets:serve
//php artisan websockets:serve --port=6001

範例畫面

範例

GitHub 範本:

https://github.com/cc711612/Online

範例網站:

https://online.usongrat.tw/

參考文獻:

https://beyondco.de/docs/laravel-websockets/getting-started/introduction

https://learnku.com/docs/laravel/8.x/broadcasting/9388#presence-channels

延伸閱讀

Comments

No comments yet.

請先登入