الموقع حالياً تحت التطوير (Beta) 🚀. قد تلاحظ بعض التغييرات أو مميزات قيد العمل.
لارافيل درس تعليمي

إتقان Laravel Echo: بناء تطبيقات الوقت الفعلي باستخدام WebSockets

Admin User
Admin User
May 17, 2026
3 دقيقة قراءة

Key Takeaways

  • # إتقان Laravel Echo: بناء تطبيقات الوقت الفعلي باستخدام WebSockets
  • في عالم الويب الديناميكي اليوم، لم تعد ميزات الوقت الفعلي رفاهية بل أصبحت توقعًا. فمن تطبيق...

إتقان Laravel Echo: بناء تطبيقات الوقت الفعلي باستخدام WebSockets

في عالم الويب الديناميكي اليوم، لم تعد ميزات الوقت الفعلي رفاهية بل أصبحت توقعًا. فمن تطبيقات الدردشة المباشرة والإشعارات الفورية إلى لوحات التحكم التفاعلية وأدوات التعاون، يطالب المستخدمون بالتحديثات الفورية. هنا يأتي دور Laravel Echo. Laravel Echo هي مكتبة JavaScript قوية تجعل دمج WebSockets في تطبيق Laravel الخاص بك أمرًا سهلاً بشكل لا يصدق، مما يسمح لك ببث الأحداث من جانب الخادم إلى الواجهة الأمامية بأقل جهد.

سيأخذك هذا البرنامج التعليمي الشامل في جولة عبر إعداد Laravel Echo، وبث الأحداث من الواجهة الخلفية الخاصة بك، والاستماع إليها في تطبيق الواجهة الأمامية الخاص بك، مما يتيح لك بناء تجارب تفاعلية حقيقية.

ما هو Laravel Echo؟ #

Laravel Echo هي مكتبة JavaScript من جانب العميل تشترك في القنوات وتستمع للأحداث التي يبثها تطبيق Laravel الخاص بك. توفر واجهة برمجة تطبيقات نظيفة ومعبرة للتعامل مع WebSockets، مما يختصر الكثير من تعقيد تفاعلات WebSocket الخام. يعمل Echo بسلاسة مع برامج تشغيل البث المختلفة، بما في ذلك Pusher و Redis (عبر Laravel Websockets) و Ably، مما يوفر مرونة في خيارات البنية التحتية الخاصة بك.

المتطلبات الأساسية #

قبل أن نبدأ، تأكد من توفر ما يلي:

  • مشروع Laravel يعمل (يوصى بالإصدار 8.x أو أعلى).
  • Composer مثبت عالميًا.
  • Node.js و NPM/Yarn مثبتين.
  • فهم أساسي لأحداث Laravel وجافاسكريبت.

الخطوة 1: إعداد الواجهة الخلفية - بث Laravel #

أولاً، نحتاج إلى تهيئة تطبيق Laravel الخاص بنا لبث الأحداث.

1. تهيئة برنامج تشغيل البث (Broadcast Driver) #

افتح ملف .env الخاص بك وعيّن BROADCAST_DRIVER إلى pusher (أو redis إذا كنت تستخدم Laravel Websockets). لهذا البرنامج التعليمي، سنستخدم Pusher لأنه سهل الإعداد.

BROADCAST_DRIVER=pusher

PUSHER_APP_ID="YOUR_APP_ID"
PUSHER_APP_KEY="YOUR_APP_KEY"
PUSHER_APP_SECRET="YOUR_APP_SECRET"
PUSHER_APP_CLUSTER="YOUR_APP_CLUSTER"

ستحتاج إلى إنشاء حساب مجاني على Pusher.com للحصول على بيانات اعتماد تطبيقك.

بعد ذلك، تأكد من تهيئة ملف config/broadcasting.php بشكل صحيح لـ Pusher:

// config/broadcasting.php

'connections' => [
    '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,
        ],
    ],
    // ... برامج تشغيل أخرى
],

2. تثبيت Pusher PHP SDK #

ثبت Pusher PHP SDK عبر Composer:

composer require pusher/pusher-php-server "~7.0"

3. إزالة التعليق عن مزود خدمة البث (Broadcast Service Provider) #

في config/app.php، تأكد من إزالة التعليق عن App\Providers\BroadcastServiceProvider::class. يسجل هذا المزود مسارات البث وعمليات رد الاتصال الخاصة بالترخيص.

// config/app.php

'providers' => [
    // ...
    App\Providers\BroadcastServiceProvider::class,
],

4. إنشاء حدث بث (Broadcast Event) #

لنقم بإنشاء حدث بسيط سيتم بثه. تخيل حدث NewMessage لتطبيق دردشة.

php artisan make:event NewMessage

افتح app/Events/NewMessage.php واجعله يطبق واجهة ShouldBroadcast. حدد أيضًا البيانات والقناة التي سيتم بثها عليها.

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class NewMessage implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $username;
    public $message;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($username, $message)
    {
        $this->username = $username;
        $this->message = $message;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('chat'); // قناة عامة
    }

    /**
     * The event's broadcast name.
     *
     * @return string
     */
    public function broadcastAs()
    {
        return 'message.new'; // اسم حدث مخصص (اختياري)
    }

    /**
     * Get the data to broadcast.
     *
     * @return array
     */
    public function broadcastWith()
    {
        return [
            'username' => $this->username,
            'text' => $this->message,
            'timestamp' => now()->toDateTimeString(),
        ];
    }
}

شرح:

  • ShouldBroadcast: تخبر هذه الواجهة Laravel ببث الحدث.
  • __construct(): ستكون البيانات التي يتم تمريرها إلى الحدث متاحة للبث.
  • broadcastOn(): تحدد القناة (القنوات) التي سيتم بث الحدث عليها. هنا، new Channel('chat') ينشئ قناة عامة.
  • broadcastAs(): (اختياري) يسمح لك بتخصيص اسم الحدث الذي يتلقاه العميل. إذا لم يتم تحديده، فإنه يستخدم اسم فئة الحدث بتنسيق kebab-case (على سبيل المثال، new-message).
  • broadcastWith(): (اختياري) يسمح لك بتخصيص الحمولة (payload) المرسلة مع الحدث. إذا لم يتم تحديده، يتم إرسال جميع الخصائص العامة للحدث.

5. إرسال الحدث (Dispatch the Event) #

الآن، يمكنك إرسال هذا الحدث من أي مكان في تطبيق Laravel الخاص بك (على سبيل المثال، وحدة تحكم، مهمة، أو خدمة).

<?php

namespace App\Http\Controllers;

use App\Events\NewMessage;
use Illuminate\Http\Request;

class ChatController extends Controller
{
    public function sendMessage(Request $request)
    {
        $username = $request->input('username', 'Guest');
        $message = $request->input('message');

        event(new NewMessage($username, $message));

        return response()->json(['status' => 'Message sent!']);
    }
}

لا تنس تحديد مسار لطريقة وحدة التحكم هذه:

// routes/web.php

Route::post('/send-message', [ChatController::class, 'sendMessage']);

الخطوة 2: إعداد الواجهة الأمامية - Laravel Echo #

الآن، دعنا نهيئ الواجهة الأمامية للاستماع لهذه الأحداث.

1. تثبيت Echo و Pusher JS #

ثبت Laravel Echo وموصل Pusher الخاص به عبر NPM أو Yarn:

npm install laravel-echo pusher-js
# أو
yarn add laravel-echo pusher-js

2. تهيئة Echo #

في إعداد Laravel نموذجي مع Vite أو Webpack، ستجد resources/js/bootstrap.js. هذا مكان جيد لتهيئة Echo. إذا كنت تستخدم إعداد واجهة أمامية مختلفًا، فتأكد من أن Pusher و 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: import.meta.env.VITE_PUSHER_APP_KEY, // لـ Vite
    // key: process.env.MIX_PUSHER_APP_KEY, // لـ Webpack Mix
    cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1',
    forceTLS: true,
});

// اختياري: الاستماع لحالة الاتصال
window.Echo.connector.pusher.connection.bind('state_change', function(states) {
    console.log('Pusher connection state:', states.current);
});

تأكد من أن ملف .env الخاص بك يحتوي على مفاتيح Pusher للواجهة الأمامية (على سبيل المثال، VITE_PUSHER_APP_KEY, VITE_PUSHER_APP_CLUSTER لـ Vite، أو بادئة MIX_ لـ Laravel Mix).

# لـ Vite (Laravel 9+)
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

# لـ Laravel Mix (إصدارات Laravel الأقدم)
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

3. تجميع الأصول (Compile Assets) #

بعد إجراء تغييرات على ملفات JavaScript الخاصة بك، قم بتجميع أصولك:

npm run dev
# أو للتجميع المستمر:
npm run watch

الخطوة 3: الاستماع إلى الأحداث #

الآن بعد تهيئة Echo، يمكنك البدء في الاستماع للأحداث.

1. القنوات العامة (Public Channels) #

القنوات العامة يمكن الوصول إليها من قبل أي شخص دون مصادقة. لقد قمنا بتعريف حدث NewMessage الخاص بنا للبث على قناة chat، والتي تكون عامة افتراضيًا.

// في مكان ما في JavaScript الواجهة الأمامية (على سبيل المثال، مكون Vue، أو مباشرة في app.js)

window.Echo.channel('chat')
    .listen('message.new', (e) => {
        console.log('تم استلام رسالة جديدة (قناة عامة):', e.username, e.text, e.timestamp);
        // قم بتحديث واجهة المستخدم هنا، على سبيل المثال، إضافتها إلى نافذة الدردشة
    });

ملاحظة: نحن نستمع إلى message.new لأننا استخدمنا broadcastAs('message.new') في حدثنا. إذا لم تحدد broadcastAs، فستستمع إلى اسم الحدث بتنسيق kebab-cased: new-message.

2. القنوات الخاصة (Private Channels) #

تتطلب القنوات الخاصة مصادقة للاشتراك فيها. يتم استخدام بادئة private- في الواجهة الخلفية لـ Laravel (على سبيل المثال، PrivateChannel('user.{id}')).

الواجهة الخلفية (الحدث والترخيص)

عدّل طريقة broadcastOn في app/Events/NewMessage.php لاستخدام قناة خاصة. لنفترض أننا نريد إرسال رسالة بشكل خاص إلى مستخدم معين.

// app/Events/NewMessage.php
// ...
public function broadcastOn()
{
    // return new Channel('chat'); // للقناة العامة
    return new PrivateChannel('user.' . $this->userId); // للقناة الخاصة
}

// ... أضف userId إلى constructor والخصائص
public function __construct($userId, $username, $message)
{
    $this->userId = $userId;
    $this->username = $username;
    $this->message = $message;
}

الآن، حدد منطق الترخيص في routes/channels.php. هذا الملف مسؤول عن تحديد ما إذا كان المستخدم المصادق عليه يمكنه الاستماع إلى قناة خاصة معينة.

// routes/channels.php

use Illuminate\Support\Facades\Broadcast;

Broadcast::channel('user.{id}', function ($user, $id) {
    return (int) $user->id === (int) $id;
});

يضمن هذا الاستدعاء أن المستخدم الذي يطابق id فقط هو من يمكنه الاشتراك في user.{id}. سيقوم Laravel تلقائيًا بتمرير المستخدم المصادق عليه ($user) والقيمة المتغيرة ($id) إلى هذا الاستدعاء.

الواجهة الأمامية

// بافتراض أن لديك طريقة للحصول على معرّف المستخدم المصادق عليه حاليًا
const currentUserId = 1; // استبدل بمعرّف المستخدم الديناميكي

window.Echo.private('user.' + currentUserId)
    .listen('message.new', (e) => {
        console.log('تم استلام رسالة جديدة (قناة خاصة):', e.username, e.text, e.timestamp);
        // تحديث واجهة المستخدم للرسائل الخاصة
    });

3. قنوات الحضور (Presence Channels) #

قنوات الحضور هي نوع خاص من القنوات الخاصة التي تمنحك وعيًا بمن هو مشترك حاليًا في القناة. هذا مثالي لميزات مثل مؤشرات "من هو متصل الآن" في غرفة الدردشة.

الواجهة الخلفية (الحدث والترخيص)

عدّل broadcastOn لقناة حضور. دعنا ننشئ قناة حضور لغرفة دردشة.

// app/Events/NewMessage.php
// ...
public function broadcastOn()
{
    return new PresenceChannel('chatroom.' . $this->chatRoomId); // لقناة الحضور
}

// ... أضف chatRoomId إلى constructor والخصائص
public function __construct($chatRoomId, $username, $message)
{
    $this->chatRoomId = $chatRoomId;
    $this->username = $username;
    $this->message = $message;
}

في routes/channels.php، حدد منطق الترخيص لقناة الحضور. يجب أن تُرجع دالة الاستدعاء لقنوات الحضور مصفوفة من البيانات حول المستخدم المصادق عليه إذا كان مرخصًا، والتي ستكون متاحة بعد ذلك لجميع أعضاء القناة.

// routes/channels.php

Broadcast::channel('chatroom.{roomId}', function ($user, $roomId) {
    if ($user->canJoinRoom($roomId)) { // نفذ منطقك للتحقق مما إذا كان المستخدم يمكنه الانضمام إلى الغرفة
        return ['id' => $user->id, 'name' => $user->name, 'avatar' => $user->avatar_url];
    }
});

الواجهة الأمامية

const currentChatRoomId = 123; // استبدل بمعرّف غرفة الدردشة الديناميكي

window.Echo.join('chatroom.' + currentChatRoomId)
    .here((users) => {
        // يتم استدعاؤها فورًا عند الانضمام. `users` هي مصفوفة بجميع الأعضاء المتواجدين حاليًا في القناة.
        console.log('المستخدمون في غرفة الدردشة:', users);
    })
    .joining((user) => {
        // يتم استدعاؤها عند انضمام مستخدم جديد إلى القناة.
        console.log(user.name + ' انضم إلى الدردشة.');
    })
    .leaving((user) => {
        // يتم استدعاؤها عند مغادرة مستخدم للقناة.
        console.log(user.name + ' غادر الدردشة.');
    })
    .error((error) => {
        // يتم استدعاؤها إذا حدث خطأ أثناء الانضمام إلى القناة.
        console.error('خطأ في الانضمام إلى غرفة الدردشة:', error);
    })
    .listen('message.new', (e) => {
        // الاستماع للأحداث العادية التي يتم بثها على قناة الحضور هذه
        console.log('رسالة جديدة في غرفة الدردشة:', e.username, e.text);
    });

الخلاصة #

يسهل Laravel Echo بشكل كبير عملية إضافة إمكانيات الوقت الفعلي لتطبيقات Laravel الخاصة بك. من خلال الجمع بين نظام بث الأحداث القوي في Laravel وواجهة برمجة تطبيقات Echo البديهية من جانب العميل، يمكنك بناء تجارب مستخدم جذابة وديناميكية بسهولة نسبية. سواء كنت بحاجة إلى إشعارات عامة بسيطة، أو رسائل خاصة آمنة، أو غرف دردشة كاملة تتسم بالوعي بالحضور، يوفر Laravel Echo الأدوات اللازمة لإنجاز المهمة بكفاءة. جرب برامج تشغيل البث المختلفة واستكشف الميزات المتقدمة مثل أحداث جانب العميل لتفاعلات الوقت الفعلي الأكثر قوة!

FAQs

ما الفرق بين القنوات العامة والخاصة وقنوات الحضور في Laravel Echo؟
القنوات العامة مفتوحة للجميع دون مصادقة. تتطلب القنوات الخاصة المصادقة والترخيص للاشتراك فيها، مما يضمن أن المستخدمين المصرح لهم فقط يمكنهم الاستماع. قنوات الحضور هي نوع خاص من القنوات الخاصة التي، بالإضافة إلى المصادقة، توفر وعيًا بالوقت الفعلي بمن هو مشترك حاليًا في القناة (على سبيل المثال، لميزات 'من المتواجد الآن').
هل أحتاج إلى خادم منفصل لـ Laravel Echo وميزات الوقت الفعلي؟
نعم، للاتصال الفعلي في الوقت الفعلي، تحتاج إلى خادم WebSocket. Laravel Echo بحد ذاته هو مكتبة من جانب العميل تتصل بهذا الخادم. تشمل الخيارات الشائعة خدمة مستضافة مثل Pusher أو Ably، أو حل مستضاف ذاتيًا مثل Laravel Websockets (الذي يستخدم Redis للبث) ويعمل على الخادم الخاص بك.
هل يمكنني استخدام Laravel Echo بدون Pusher؟
بالتأكيد! بينما Pusher هو خيار شائع وسهل التهيئة، يدعم Laravel Echo برامج تشغيل بث أخرى. يمكنك استخدام Redis مع حزمة Laravel Websockets لحل مستضاف ذاتيًا، أو التكامل مع خدمات أخرى مثل Ably. ما عليك سوى تغيير `BROADCAST_DRIVER` في ملف `.env` وتهيئة Echo وفقًا لذلك.

Want more content like this?

Explore more tutorials in the لارافيل section.

Explore لارافيل

You might also like

لارافيل
6 دقيقة قراءة

بايبر (Piper): إطلاق قوة مصفوفات وسلاسل لارافيل في PHP الخالصة باستخدام عامل الأنبوب

تُعد أساليب التعامل مع المصفوفات والسلاسل النصية بمرونة في لارافيل متعة حقيقية، حيث توفر طرقًا موجزة ومقروءة لتحويل البيانات. ماذا لو كان بإمكانك جلب نفس هذه ال...

May 23, 2026
اقرأ