Laravel Reverbとは——PHPネイティブなWebSocketサーバー
Laravel Reverbは2024年3月のLaravel 11と同時にリリースされた、Laravelアプリにネイティブ統合できるWebSocketサーバーです。従来はPusher・Soketi・SocketIOなどの外部サービス・ツールが必要でしたが、Reverbを使えば追加コストなしで自前のWebSocketサーバーを運用できます。
インストール
composer require laravel/reverb
php artisan reverb:install
# → config/reverb.php が生成される
# → .env に REVERB_* 変数が追加される
# フロントエンドライブラリのインストール
npm install --save-dev laravel-echo pusher-js
環境設定
# .env
BROADCAST_CONNECTION=reverb
REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-secret
REVERB_HOST=localhost
REVERB_PORT=8080
REVERB_SCHEME=http
ブロードキャストイベントの定義
// app/Events/ReservationStatusUpdated.php
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class ReservationStatusUpdated implements ShouldBroadcast
{
use Dispatchable, SerializesModels;
public function __construct(
public readonly Reservation $reservation,
) {}
// イベントのブロードキャスト先チャンネル
public function broadcastOn(): array
{
return [
// プライベートチャンネル(認証が必要)
new PrivateChannel("reservations.{$this->reservation->id}"),
// 管理者向けチャンネル
new PrivateChannel('admin.reservations'),
];
}
// ブロードキャストするデータ
public function broadcastWith(): array
{
return [
'reservation_id' => $this->reservation->id,
'status' => $this->reservation->status,
'updated_at' => $this->reservation->updated_at->toIso8601String(),
'customer_name' => $this->reservation->customer_name,
];
}
// イベント名のカスタマイズ
public function broadcastAs(): string
{
return 'reservation.status.updated';
}
}
チャンネル認証
// routes/channels.php
use App\Models\Reservation;
// ユーザーが自分の予約チャンネルにアクセスできるか認証
Broadcast::channel('reservations.{reservationId}', function ($user, int $reservationId) {
$reservation = Reservation::find($reservationId);
return $reservation && $reservation->user_id === $user->id;
});
// 管理者のみアクセス可能
Broadcast::channel('admin.reservations', function ($user) {
return $user->isAdmin();
});
イベントのdispatch
// コントローラー
class ReservationController extends Controller
{
public function confirm(Reservation $reservation): JsonResponse
{
$reservation->update(['status' => 'confirmed']);
// イベントをブロードキャスト
ReservationStatusUpdated::dispatch($reservation);
return response()->json(['message' => '予約を確定しました']);
}
}
フロントエンドの実装
// resources/js/bootstrap.js
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
// 予約状況のライブ更新
window.Echo.private(`reservations.${reservationId}`)
.listen('.reservation.status.updated', (event) => {
console.log('予約ステータス更新:', event.status);
// DOM更新
const statusEl = document.getElementById('reservation-status');
if (statusEl) {
statusEl.textContent = getStatusLabel(event.status);
statusEl.className = `status-badge status-${event.status}`;
}
// トースト通知
showToast(`予約ステータスが「${getStatusLabel(event.status)}」に更新されました`);
});
// 管理者ダッシュボード
window.Echo.private('admin.reservations')
.listen('.reservation.status.updated', (event) => {
// 管理者向けリアルタイム更新
updateAdminDashboard(event);
});
Reverbサーバーの起動
# 開発環境
php artisan reverb:start
# デバッグモード
php artisan reverb:start --debug
# 本番環境(Supervisorで常時起動)
; /etc/supervisor/conf.d/reverb.conf
[program:reverb]
command=php /var/www/html/artisan reverb:start --host=0.0.0.0 --port=8080
autostart=true
autorestart=true
user=www-data
まとめ
Laravel Reverbにより、外部サービスへの依存なしに自前のWebSocket機能を低コストで実装できます。予約システム・チャット・リアルタイム在庫管理など、ライブ更新が必要な機能に最適です。弊社では予約管理システムのリアルタイム更新をReverbで実装しています。
LaravelによるWebシステム開発のご相談はお気軽にどうぞ。