الوقت الفعلي مع Laravel (Pusher والبث)
يوفر Laravel نظام بث قوي يسهل بناء تطبيقات الوقت الفعلي. في هذا الدرس، سنستكشف كيفية استخدام ميزات البث في Laravel مع Pusher وLaravel Echo.
فهم نظام البث في Laravel
يتيح نظام البث في Laravel بث الأحداث من جانب الخادم إلى تطبيقات JavaScript من جانب العميل باستخدام WebSockets.
ملاحظة: نظام البث في Laravel يخفي تعقيد تطبيقات WebSocket، مما يتيح لك التركيز على منطق التطبيق الخاص بك.
إعداد Pusher
أولاً، قم بتثبيت Pusher PHP SDK:
composer require pusher/pusher-php-server
قم بتكوين برنامج تشغيل البث في .env:
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=your-app-id
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_APP_CLUSTER=mt1
قم بتحديث config/broadcasting.php للتأكد من تكوين Pusher:
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => true,
],
],
إنشاء أحداث البث
قم بإنشاء حدث بث جديد:
php artisan make:event MessageSent
قم بتنفيذ فئة الحدث:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
public $user;
public function __construct($message, $user)
{
$this->message = $message;
$this->user = $user;
}
public function broadcastOn()
{
return new Channel('chat');
}
public function broadcastAs()
{
return 'message.sent';
}
public function broadcastWith()
{
return [
'message' => $this->message,
'user' => $this->user->name,
'timestamp' => now()->toDateTimeString(),
];
}
}
نصيحة: استخدم broadcastAs() لتخصيص اسم الحدث الذي يستمع له العملاء، وbroadcastWith() للتحكم في البيانات المرسلة.
بث الأحداث
قم بإرسال الحدث من المتحكم الخاص بك:
use App\Events\MessageSent;
public function sendMessage(Request $request)
{
$message = $request->input('message');
$user = auth()->user();
// حفظ الرسالة في قاعدة البيانات
$chat = Chat::create([
'user_id' => $user->id,
'message' => $message,
]);
// بث الحدث
broadcast(new MessageSent($message, $user));
return response()->json(['success' => true]);
}
القنوات الخاصة
للبث الخاص بالمستخدم، استخدم القنوات الخاصة:
public function broadcastOn()
{
return new PrivateChannel('user.' . $this->user->id);
}
حدد منطق التفويض في routes/channels.php:
Broadcast::channel('user.{userId}', function ($user, $userId) {
return (int) $user->id === (int) $userId;
});
قنوات الحضور
قنوات الحضور مثالية لإظهار من هو متصل:
use Illuminate\Broadcasting\PresenceChannel;
public function broadcastOn()
{
return new PresenceChannel('chat.room');
}
قم بتفويض قنوات الحضور:
Broadcast::channel('chat.room', function ($user) {
return [
'id' => $user->id,
'name' => $user->name,
'avatar' => $user->avatar_url,
];
});
إعداد Laravel Echo
قم بتثبيت Laravel Echo وPusher JS في الواجهة الأمامية:
npm install --save laravel-echo pusher-js
قم بتكوين Echo في resources/js/bootstrap.js:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
forceTLS: true
});
الاستماع للأحداث باستخدام Echo
استمع لأحداث القناة العامة:
Echo.channel('chat')
.listen('.message.sent', (e) => {
console.log('رسالة جديدة:', e.message);
console.log('من:', e.user);
// تحديث واجهة المستخدم بالرسالة الجديدة
appendMessage(e.user, e.message, e.timestamp);
});
استمع للقنوات الخاصة:
Echo.private('user.' + userId)
.listen('NotificationSent', (e) => {
showNotification(e.title, e.message);
});
تحذير: القنوات الخاصة تتطلب المصادقة. تأكد من أن المستخدم الخاص بك قد سجل الدخول وأن مسار /broadcasting/auth متاح.
العمل مع قنوات الحضور
انضم إلى قناة حضور وتتبع المستخدمين:
Echo.join('chat.room')
.here((users) => {
console.log('متصلون حالياً:', users);
updateOnlineUsersList(users);
})
.joining((user) => {
console.log(user.name + ' انضم');
addUserToList(user);
})
.leaving((user) => {
console.log(user.name + ' غادر');
removeUserFromList(user);
})
.listen('.message.sent', (e) => {
appendMessage(e.user, e.message, e.timestamp);
});
أحداث العميل
إرسال أحداث من عميل إلى عميل (فقط على قنوات الحضور/الخاصة):
// إرسال مؤشر الكتابة
Echo.join('chat.room')
.whisper('typing', {
name: currentUser.name
});
// الاستماع لمؤشرات الكتابة
Echo.join('chat.room')
.listenForWhisper('typing', (e) => {
showTypingIndicator(e.name);
});
نصيحة: أحداث العميل (الهمسات) لا تصل إلى الخادم الخاص بك، مما يجعلها مثالية للحالات المؤقتة مثل مؤشرات الكتابة أو مواقع المؤشر.
بث الإشعارات
يمكن بث إشعارات Laravel تلقائياً:
<?php
namespace App\Notifications;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class NewFollower extends Notification implements ShouldBroadcast
{
public function via($notifiable)
{
return ['broadcast', 'database'];
}
public function toBroadcast($notifiable)
{
return [
'follower_name' => $this->follower->name,
'follower_avatar' => $this->follower->avatar_url,
];
}
}
استمع للإشعارات:
Echo.private('App.Models.User.' + userId)
.notification((notification) => {
console.log('تم استلام إشعار:', notification);
showToast(notification.follower_name + ' تابعك!');
});
وضع البث في قائمة الانتظار لتحسين الأداء
استخدم ShouldBroadcastNow للبث الفوري أو ضعها في قائمة الانتظار:
// بث فوري
class MessageSent implements ShouldBroadcastNow
{
// ...
}
// بث في قائمة الانتظار (أفضل لحركة المرور العالية)
class MessageSent implements ShouldBroadcast
{
// ...
}
تمرين: أنشئ تطبيق Laravel مع إشعارات في الوقت الفعلي. عندما ينشئ مستخدم منشوراً جديداً، قم ببث إشعار لجميع المتابعين. استخدم قنوات الحضور لإظهار المتابعين المتصلين حالياً. قم بتنفيذ مؤشر "كتابة" للتعليقات باستخدام أحداث العميل.