البث (Broadcasting) في Laravel

من موسوعة حسوب
اذهب إلى: تصفح، ابحث

مقدمة

في العديد من التطبيقات الحديثة، تُستعمل Websockets لتنفيذ واجهات استخدام فورية ذات تحيين مباشر. عند رفع بعض البيانات للخادم، تُرسَل في العادة رسالة على اتصال websocket لتُعالَج من قبل العميل. يوفّر هذا بديلًا فعالًا للسحب المتواصل للتطبيق من أجل التغييرات. لمساعدتك في بناء هذا النوع من التطبيقات، يجعل Laravel من السهل "بث" أحداث عبر صلة websocket. يسمح بث الأحداث بمشاركة نفس الأحداث بين شيفرة من جهة الخادم وشيفرة من جهة العميل.

ملاحظة: قبل التعمق في بث الأحداث، تأكد من قراءة توثيق Laravel الخاص بالأحداث والمستمعات.

الضبط

تُخزّن كل خيارات ضبط البث في الملف config/broadcast.php. يدعم Laravel برامج تشغيل بث عديدة من البداية مثل Pusher و Redis والمشغل المحلي log للبرمجة والإصلاح. وتتوافر أيضًا القيمة null مما يسمح بالتعطيل الكامل لعملية البث. يوجد مثال ضبط لكل هذه المشغلات في الملف config/broadcast.php.

مزودو خدمات البث

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

الرمز المميز CSRF

يحتاج Laravel Echo الولوج لرموز CSRF للدورة الحالية. يجب أن تتأكد من أنّ العنصر <head> في HTML يعرف العنصر <meta> الذي يحتوي على الرمز CSRF:
<meta name="csrf-token" content="{{ csrf_token() }}">

متطلبات المشغّل

Pusher

إذا كنت تبث الأحداث باستخدام Pusher، فيجب عليك تثبيت Pusher PHP SDK باستعمال منظم الحزم Composer:

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

ثم يتوجب عليك دفع اعتمادات Pusher للملف config/broadcast.php. يتضمن الملف مثال ضبط Pusher مما يسمح لك بتخصيص مفتاح، وسر، ومعرف Pusher بسرعة. يسمح مثال الضبط بتخصيص خيارات options أخرى يدعمها Pusher مثل cluster.

'options' => [

   'cluster' => 'eu',
   'encrypted' => true
]

عند استعمال Pusher و Laravel ECHO، يجب تحديد pusher كخيار البث عند بدء نسخة Echo في الملف resources/assets/js/bootstrap.js:

import Echo from "laravel-echo"

window.Pusher = require('pusher-js');

window.Echo = new Echo({

   broadcaster: 'pusher',
   key: 'your-pusher-key'
});

Redis

إذا كنت تستعمل الباث Redis، يجب عليك تثبيت المكتبة Predis:
composer require predis/predis

يبث Redis الأحداث باستخدام الخاصية pub/sub لكن عليك إضافة خادم Websocket ليتلقى رسائل Redis و يبثها لقنوات Websocket.

عندما يبث Redis حدثًا، فسيُنشر على القناة المخصصة للحدث وسيحمل سلسلة محارف مشفرة بطريقة JSON تتضمن اسم الحدث ومعلومات data ومعرف المستخدم الذي صنع التوصيل socket (إن أمكن).

Socket.io

إذا كنت ستضيف Socket.io للباث Redis، ستحتاج لإضافة مكتبة عميل JavaScript للتطبيق. يمكنك تثبيته عبر منظم الخدمات NPM:
npm install --save socket.io-client

ثم عليك بدء Echo بموصل socket.io و host:

import Echo from "laravel-echo"

window.io = require('socket.io-client');

window.Echo = new Echo({

   broadcaster: 'socket.io',
   host: window.location.hostname + ':6001'
});

أخيرا، عليك تشغيل خادم Socket.io متوافق. لا يتضمن Laravel خادم socket.io لكن هنالك خادمٌ يتكفل به المجتمع موجودٌ في github في المستودع tlaverdure/laravel-echo-server.

متطلبات طوابير الانتظار

قبل بث الأحداث, ستحتاج لضبط و تشغيل مستمعي طوابير الانتظار. يتم البث عن طريق مهمات موجودة في قائمات انتظار حتى لا يتأثر وقت اجابة التطبيق.

نظرة عامة على مفهوم البث

يسمح بث الأحداث في Laravel ببث أحداث من جهة الخادم إلى سكربات JavaScript التابعة لتطبيقك من جهة العميل باستخدام مقاربة مبنية على المشغلات في Websockets.

تبث الأحداث في قنوات "channels" قد تكون عامة أو خاصة. يمكن لأي مستخدم للتطبيق أن ينخرط في قناة عامة دون الحاجة لترخيص أو استيثاق. لكن للاستماع على قناة خاصة لا بد من الاستيثاق والترخيص.

استخدام تطبيق مثال

قبل التعمق في كل مكون من بث الأحداث، لنأخذ نظرة عامة على تطبيق تسوق إلكتروني على سبيل المثال. لن ندقق في ضبط Pusher أو Laravel Echo لأن ذلك مذكور في أقسام أخرى من التوثيق.

لنفترض أنّ لدينا في هذا التطبيق صفحة تسمح للمستخدم بالإطلاع على حالة شحن طلب معين. لنفترض أيضًا أن الحدث ShippingStatusUpdated يُطلق كلما تم تحديث حالة طلب شحن يعالجه التطبيق:
event(new ShippingStatusUpdated($update));

الواجهة ShouldBroadcast

عندما يطّلع المستخدم على أحد طلباته، لا نريده أن يُحدّث الصفحة ليرى تحيين الحالة. بل نريد بث تحديثات التطبيق عند إنشائها. لذا يجب إضافة الواجهة ShouldBroadcast للحدث ShippingStatusUpdated. مما سيخبر Laravel أن يبث الحدث عند إطلاقه:
<?php

namespace App\Events;

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

class ShippingStatusUpdated implements ShouldBroadcast

{

   /**
    * معلومات عن حالة الشحن.
    *
    * @var string
    */
   public $update;
}

تتطلب الواجهة من صنف الحدث تعريف التابع broadcastOn. هذا التابع مسؤول عن إعادة القنوات التي على الحدث البث عليها. يكون التابع فارغًا في كل أصناف الأحداث المُنتجَة ونحتاج فقط لملء التفاصيل. نريد لصاحب الطلب فقط أن يرى حالة الشحن لذا سنبث الحدث على قناة خاصة مرتبطة بالطلب.

/**

* الحصول على معلومات على قناة البث.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()

{

   return new PrivateChannel('order.'.$this->update->order_id);
}

ترخيص القنوات

تذكر انّ المستخدم يجب أن يسجل الدخول ليستمع للقنوات الخاصة. يمكن تعريف قواعد تراخيص القناة في routes/channels.php. في هذا المثال، يجب التأكد من أن المستخدم الذي يريد الاستماع على القناة الخاصة order.1 هو صاحب الطلب:
Broadcast::channel('order.{orderId}', function ($user, $orderId) {

   return $user->id === Order::findOrNew($orderId)->user_id;
});

يقبل التابع channel معاملين: اسم القناة ونداء يُرجع القيمة true أو false للدلالة على إذا كان المستخدم يملك ترخيصًا للاستماع على القناة أم لا. كل نداءات التراخيص تتلقى المستخدم المسجل حاليا كمعامل أول و معامل بديل عن أي معامل إضافي. في هذا المثال، نستخدم البديل {orderId} للإعلام أنّ القسم "ID" من اسم القناة متغير.

الاستماع لبث الحدث

بعد ذلك، كل ما تبقى هو الإستماع للحدث في شيفرة JavaScript للتطبيق. يمكن القيام بهذا باستعمال Laravel Echo. أولًا، نستعمل التابع private للدخول إلى القناة الخاصة. ثم، يمكننا استعمال التابع listen للاستماع للحدث ShippingStatusUpdated. في العادة، كل الخاصيات العامة للحدث تُضمَّن في حدث البث:
Echo.private(`order.${orderId}`)

   .listen('ShippingStatusUpdated', (e) => {
       console.log(e.update);
   });

تعريف أحداث البث

لإعلام Laravel أن حدثا ما يجب بثّه، نفذ الواجهةIlluminate\Contracts\Broadcasting\ShouldBroadcast في صنف الحدث. تُحمَّل هذه الواجهة في كل أصناف الأحداث لذا يمكنك إضافتها بسهولة لأي حدث.

تتطلب الواجهة ShouldBroadcast كتابة تابع وحيد هو broadcastOn. يعيد هذا التابع قناة أو مصفوفة قنوات يبث عليها الحدث. يجب أن تكون القناة نسخة Channel أو PrivateChannel أو PresenceChannel. تمثل نسخة Channel القنوات العامة التي يمكن لأي مستخدم الدخول فيها في حين PrivateChannel و PresenceChannel تمثل قنوات تتطلب ترخيصًا:
<?php

namespace App\Events;

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

class ServerCreated implements ShouldBroadcast {

   use SerializesModels;
   public $user;
   /**
    * إنشاء نسخة حدث جديد
    *
    * @return void
    */
   public function __construct(User $user)
   {
       $this->user = $user;
   }
   /**
    * جلب القنوات التي يجب من الحدث البث فيها
    *
    * @return Channel|array
    */
   public function broadcastOn()
   {
       return new PrivateChannel('user.'.$this->user->id);
   }
}

ثم عليك إطلاق حدث كما تفعل عادة. عند إطلاق الحدث، تبث مهمة في قائمة الإنتظار آليًا الحدث على المشغل الذي اخترته.

اسم البث

في العادة، يبث Laravel الأحداث باستخدام أسماء أصناف الأحداث. لكن بإمكانك تخصيص اسم البث عبر تعريف التابع broadcastAs في الحدث:
/**

* اسم الحدث.
*
* @return string
*/
public function broadcastAs() {

   return 'server.created';
}
إذا غيّرت اسم البث باستخدام broadcastAs، يجب عليك التأكد من تسجيل المستمع مسبوقًا بالرمز ".". سيُخبر هذا Echo بإضافة مجال أسماء للحدث:
.listen('.server.created', function (e) {

   ....
});

بيانات البث

عند بث حدث، تتم سلسلة كل خاصياته العامة آليًا كتحميل للحدث، مما يسمح لك بالولوج لكل بياناته العامة من تطبيق JavaScript. لذا لو كان للحدث خاصية واحدة user$ مثلًا تحتوي على نموذج Eloquent، يكون نحميل البث كما يلي:

{

   "user": {
       "id": 1,
       "name": "Patrick Stewart"
       ...
   }
}
لكن إذا أردت تحكما أفضل في تحميل البث، يمكنك إضافة التابع broadcastWith. يعيد هذا التابع مصفوفة البيانات التي تريد إرسالها كتحميل للبث:
/**

* بيانات البث
*
* @return array
*/
public function broadcastWith() {

   return ['id' => $this->user->id];
}

طابور انتظار البث

في العادة، يوضع كل أحداث البث في طابور الانتظار الأولية للصلة الأولية المعرّفة في ملف الضبط queue.php. يمكنك تخصيص طابور انتظار البث عبر تعريف الخاصية broadcastQueue في صنف الحدث. يجب أن تحدد هذه الخاصية اسم طابور الانتظار الذي تود استعماله عند البث:
/**

* اسم قائمة الإنتظار.
*
* @var string
*/
public $broadcastQueue = 'your-queue-name';

إذا أردت بث الأحداث باستعمال طابور الانتظار sync بدل المشغل العادي، يمكنك تنفيذ shouldBroadcastNow بدل ShouldBoradcast:

<?php

use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;

class ShippingStatusUpdated implements ShouldBroadcastNow

{

  //
}

شروط البث

في بعض الأحيان، قد تريد بث الأحداث فقط إن تحقق شرط معين. يمكنك تحديد هذه الشروط عبر إضافة التابع broadcastWhen لصنف الحدث:
/**

* تحديد إذا كان يجب بث الحدث
*
* @return bool
*/
public function broadcastWhen() {

   return $this->value > 100;
}

الترخيص للقنوات

تتطلب القنوات الخاصة ترخيصًا ليتمكن المستخدم المسجل حاليًا من الإستماع إليها. يتم هذا عبر إطلاق طلب HTTP للتطبيق باسم القناة وجعل التطبيق يقرر هل يسمح للمستخدم بالإستماع أم لا. عند استخدام Laravel Echo، يُصنع طلب HTTP للترخيص بالإنخراط في القنوات الخاصة تلقائيًا. لكن عليك تعريف المسار للإجابة على الطلب.

تعريف مسارات الترخيص

من حسن الحظ، يجعل Laravel تعريف المسارات لإجابة طلبات الترخيص أمرًا سهلًا. في مزود الخدمات BroadcastServiceProvider المضمن في تطبيق Laravel، سترى نداء للتابع Broadcast::routes. سيسجل هذا التابع المسار broadcasting/auth لمعالجة طلبات الترخيص.
Broadcast::routes();
يضع التابع Broadcast::routes آليًا مساراته في في مجموعة الوسيط web لكن بإمكانك تمرير أي صفوفة من خصائص المسارات للتابع إذا أردت تخصيص الخاصيات.
Broadcast::routes($attributes);

تعريف نداءات الترخيص

بعد ذلك، نحتاج لتعريف التحكم المنطقي الذي سيقوم بالترخيص. يتم هذا في الملف routes/channels.php في التطبيق. في هذا الملف، يمكنك استخدام التابع Broadcast::channel لتسجيل نداءات ترخيص القنوات:
Broadcast::channel('order.{orderId}', function ($user, $orderId) {

   return $user->id === Order::findOrNew($orderId)->user_id;
});

يقبل التابع channel معاملين وهما اسم القناة ودالة رد نداء تعيد القيمة true أو false للدلالة على إذا كان المستخدم يملك ترخيصًا للاستماع أم لا. كل نداءات التراخيص تتلقى المستخدم المسجل حاليًا كمعامل أول و معامل بديل عن أي معامل إضافي. في المثال السابق، نستخدم البديل {orderId} للإعلام أنّ القسم "ID" من اسم القناة متغير.

ترخيص نداءات ربط النماذج

مثل مسارات HTTP، تستفيد مسارات القنوات من ربط النماذج المباشر و غير المباشر. مثلًا، بدل تلقي سلسلة محارف أو معرّف رقمي، يمكن أن تطلب نسخة من Order:

use App\Order;

Broadcast::channel('order.{order}', function ($user, Order $order) {

   return $user->id === $order->user_id;
});

تعريف أصناف القنوات

إذا كان التطبيق يستعمل العديد من القنوات، سيصبح الملف routes/channels.php ضخمًا. لذا، بدل استعمال Closure لترخيص القنوات، يمكن استعمال أصناف للقنوات. لإنشاء أصناف القنوات، استعمل الأمر make:channel. سيضع الأمر الأصناف المصنوعة في المجلد App/Broadcasting
php artisan make:channel OrderChannel
ثم سجل الصنف في الملف routes/channels.php
use App\Broadcasting\OrderChannel;

Broadcast::channel('order.{order}', OrderChannel::class);
أخيرًا، يمكنك وضع التحكم المنطقي في الترخيص في الصنف في التابع join. سيحتوي هذا التابع نفس الشيفرة التي كنت ستضعها في عادة في القسم Closure. يمكن طبعًا الاستفادة من ربط النماذج هنا أيضًا.
<?php

namespace App\Broadcasting;

use App\User; use App\Order;

class OrderChannel {

   /**
    * إنشاء نسخة قناة جديدة
    *
    * @return void
    */
   public function __construct()
   {
      //
   }
   /**
    * استيثاق مستخدم القناة
    *
    * @param  \App\User  $user
    * @param  \App\Order  $order
    * @return array|bool
    */
   public function join(User $user, Order $order)
   {
       return $user->id === $order->user_id;
   }
}

ملاحظة: كالعديد من الأصناف في Laravel، تُعالج أصناف القنوات في حاوي الخدمات. لذا يمكنك التلميح إلى نوع الإعتماديات التي تحتاج لها القناة في باني الصنف التي يحتاجها باني الصنف.

بث الأحداث

بعد تعريف الحدث وإضافة الواجهة ShouldBroadcast، تحتاج فقط لإطلاق الحدث باستعمال الدالة event. سيُلاحظ مُطلِق الأحداث أن الحدث تم ترميزه بالواجهة ShouldBroadcast ويضيفه لقائمة انتظار البث:
event(new ShippingStatusUpdated($update));

فقط للآخرين

عند بناء تطبيق يستعمل تقنية البث، يمكنك تعويض الدالة event بالدالة broadcast. مثل event، يُطلق broadcast الحدث من جهة الخادم للمستمع في جهة العميل
broadcast(new ShippingStatusUpdated($update));
لكن الدالة broadcast توفر أيضًا التابع toOthers الذي يسمح باستثناء المستخدم الحالي من لائحة المستقبلين:
broadcast(new ShippingStatusUpdated($update))->toOthers();
لفهم أفضل متى قد تريد استعمال التابع toOthers، لنتخيل تطبيقا للائحة مهام حيث يمكن للمستخدم صناعة مهمة جديدة بتمرير اسم المهمة. لإنشاء مهمة، يبعث التطبيق طلبًا لنقطة النهاية task/ التي تبث صناعة المهمة وتعيد تمثيل JSON للمهمة الجديدة. يتلقى تطبيق javascript الجواب من نقطة النهاية، يمكنه إضافة المهمة الجديدة للائحته كالآتي
axios.post('/task', task)

   .then((response) => {
       this.tasks.push(response.data);
   });

لكن تذكر أننا نبث أيضًا صناعة المهمة، إذا كان تطبيق JavaScript يستمع للحدث ليضيف المهام الجديدة للائحة المهام، سيكون لديك نفس المهمة مرتين: واحد من نقطة النهاية وواحد من البث. يمكن حل هذا المشكل باستخدام التابع toOthers لإعلام الباث بعدم بث الحدث للمستخدم الحالي.

تنبيه: يجب على الحدث استخدام الخاصية Illuminate\Broadcasting\InteractsWithSockets للاستعمال التابع toOthers.

الضبط

عند بدء مثيل Laravel Echo، يُعطى معرّف توصيل (Socket id) للصلة. إذا كنت تستخدم Vue و Axios، يُرفق المعرّف تلقائيًا بكل طلب خارج كعنوان x-socket-ID. ثم عندما تنادي التابع toOthers، يأخذ Laravel المعرّف من العنوان ويأمر الباث بعدن البث لأي صلة تحمل ذلك المعرّف.

إذا كنت لا تستخدم Vue و Axios، ستحتاج لضبط تطبيق JavaScript يدويًا ليُرسل العنوان x-socket-ID. يمكنك استرجاع معرّف التوصيل بالتابع Echo.socketID:

var socketId = Echo.socketId();

تلقي البث

تثبيت Laravel echo

Laravel Echo هي مكتبة Javascript تجعل الانخراط في قناة و والإستماع للأحداث أمرًا سهلًا. يمكنك تثبيت Echo عبر منظم الحزم NPM. في هذا المثال، سنثبت أيضًا pusher-js حيث سنستخدم المشغل pusher للبث:
npm install --save laravel-echo pusher-js
بعد تثبيت Echo، أنت الآن جاهزٌ لإنشاء نسخة Echo في تطبيق JavaScript. نهاية الملف resources/assets/js/bootstrap.js هي مكان جيد للقيام بهذا:
import Echo from "laravel-echo"

window.Echo = new Echo({

   broadcaster: 'pusher',
   key: 'your-pusher-key'
});
عند إنشاء نسخة Echo يستخدم الباث pusher، يمكنك أيضًا تخصيص cluster بالإضافة إلى تحديد إذا ما كانت الصلة تستوجب تشفيرًا:
window.Echo = new Echo({

   broadcaster: 'pusher',
   key: 'your-pusher-key',
   cluster: 'eu',
   encrypted: true
});

الاستماع للأحداث

بعد تثبيت Echo و تشغيله، أنت الآن جاهز للاستماع للأحداث. أولًا، استخدم التابع channel لإعادة نسخة من القناة، ثم استدع التابع listen لحدث معين:
Echo.channel('orders')

   .listen('OrderShipped', (e) => {
       console.log(e.order.name);
   });
إذا أردت الاستماع لأحداث في قناة خاصة، استعمل التابع private بدل channel. يمكنك المواصلة في إضافة نداءات listen للاستماع لعدة أحداث في قناة واحدة
Echo.private('orders')

   .listen(...)
   .listen(...)
   .listen(...);

مغادرة قناة

لمغادرة قناة، ينكنك نداء التابع leave في نسخة Echo:
Echo.leave('orders');

مجالات الأسماء

قد تكون لاحظت في الأمثلة السابقة أننا لم نحدد مجال اسم (namespace) كامل لأصناف الأحداث. هذا لأن Echo يتوقع تلقائيا أن الأحداث موجودة في مجال الأسماء App\Events. لكن يمكنك ضبط جذر مجال الأسماء عند تشغيل Echo بتمرير خيار الضبط namespace
window.Echo = new Echo({

   broadcaster: 'pusher',
   key: 'your-pusher-key',
   namespace: 'App.Other.Namespace'
});
طريقة أخرى هي سبق أصناف الأحداث بنقطة "." عند الانخراط فيها باستعمال Echo. سيسمح لك هذا بذكر اسم كامل للصنف
Echo.channel('orders')

   .listen('.Namespace.Event.Class', (e) => {
      //
   });

قنوات الحضور

تبني قنوات الحضور (presence) على أمان القنوات الخاصة في حين تستغل الخاصية الإضافية بالعلم بمن ينخرط في القناة. مما يسهل من بناء خاصيات قوية وتشاركية مثل تنبيه المستخدم حين يرى مستخدم آخر نفس الصفحة.

ترخيص قنوات الحضور

كل قنوات الحضور قنواتٌ خاصةٌ، لذا، يجب الترخيص للمستخدمين لاستعمالها. لكن عند تعريف نداء ترخيص لقناة حضور، لن تعيد true إذا كان المستخدم مرخصًا له بل يجب أن تعيد مصفوفة ببيانات المستخدم. تكون البيانات الموفّرة من قبل نداء الترخيص متوفِّرة لمستمعي قنوات الحضور في تطبيق JavaScript. إذا لم يكن المستخدم مرخصًا له لدخول القناة، فيجب أن تعيد false أو null:

Broadcast::channel('chat.{roomId}', function ($user, $roomId) {

   if ($user->canJoinRoom($roomId)) {
       return ['id' => $user->id, 'name' => $user->name];
   }
});

الانضمام لقنوات الحضور

للانضمام لقنوات الحضور، يمكنك استعمال التابع join. سيعيد هذا التابع تنفيذًا للتابع PresenceChannel الذي، بالإضافة لتوفير التابع listen، يسمح أيضا بالانخراط في الأحداث here و joining و leaving.

Echo.join(`chat.${roomId}`)

   .here((users) => {
      //
   })
   .joining((user) => {
       console.log(user.name);
   })
   .leaving((user) => {
       console.log(user.name);
   });

يُنفَّذ النداء here مباشرة عند الانضمام الناجح للقناة، ويتلقى مصفوفة من بيانات المستخدم لبقية المستخدمين المنخرطين في القناة. يُنفَّذ التابع joining عندما انضم مستخدم جديد في حين ينفَّذ التابع leaving عندما يغادر مستخدم القناة.

البث لقنوات الحضور

تتلقى قنوات الحضور أحداثًا مثل القنوات العامة أو الخاصة. باستخدام مثال غرف الرسائل، قد نريد بث الحدث NewMessage لقناة حضور الغرفة. للقيم بذلك، سنعيد نسخة PresenceChannel من التابع broadcastOn في الحدث:
/**

*الحصول على قناة البث.
*
* @return Channel|array
*/
public function broadcastOn() {

   return new PresenceChannel('room.'.$this->message->room_id);
}
مثل القنوات العامة والخاصة، يمكن بث أحداث في قنوات الحضور باستخدام الدالة broadcast. كما في بقية الأحداث، يإمكانك استخدام التابع toOthers لاستثناء المستخدم الحالي من تلقي البث:
broadcast(new NewMessage($message));

broadcast(new NewMessage($message))->toOthers();

يمكنك الإستماع لأحداث الإنضمام عبر التابع listen:

Echo.join(`chat.${roomId}`)

   .here(...)
   .joining(...)
   .leaving(...)
   .listen('NewMessage', (e) => {
      //
   });

أحداث العملاء

ملاحظة: عند استعمال Pusher، عليك تفعيل الخيار "Client Events" في القسم "App Settings" من لوحة التحكم لقبول الأحداث من جهة العملاء.

قد تريد في بعض الأحيان بث حدث لبقية المستخدمين دون المرور بتطبيق Laravel. يكون هذا مفيدًا في حالات مثل تنبيهات الكتابة، أين يمكنك أن تُعلم المستخدم أنّ مستخدمًا آخر بصدد الكتابة في شاشة معينة.

لبث أحداث العملاء، يمكن استخدام التابع whisper:

Echo.private('chat')

   .whisper('typing', {
       name: this.user.name
   });
للاستماع لأحداث العملاء، استخدم التابع listenForWhisper:
Echo.private('chat')
    .listenForWhisper('typing', (e) => {
        console.log(e.name);
    });

الإشعارات

عبر إرفاق بث الأحداث بالإشعارات، يتلقى تطبيق JavaScript الإشعارات حين تصل دون الحاجة لتحديث الصفحة. أولا، تأكد من الاطلاع على توثيق الإشعارات.

بعد ضبط التنبيهات لاستخدام قنوات البث، يمكنك الإستماع للأحداث باستعمال التابع notification. تذكر أن اسم القناة يجب أن يوافق اسم صنف الكائن المتلقي لللإشعار:
Echo.private(`App.User.${userId}`)

   .notification((notification) => {
       console.log(notification.type);
   });

في هذا المثال، يتلقى النداء كل التنبيهات المبعوثة إلى App\User عبر القناة broadcast. نداء ترخيص للقناة App.User.{id} يكون مضمنًا في مزود الخدمات BroadcastServiceProvider الذي يأتي مع الإطار Laravel.

مصادر