الفرق بين المراجعتين لصفحة: «Laravel/broadcasting»
سطر 399: | سطر 399: | ||
=== بث الأحداث === | === بث الأحداث === | ||
بعد تعريف الحدث وإضافة الواجهة | بعد تعريف الحدث وإضافة الواجهة <code>ShouldBroadcast</code>، تحتاج فقط لإطلاق الحدث باستعمال الدالة <code>event</code>. سيُلاحظ مُطلِق الأحداث أن الحدث تم ترميزه بالواجهة <code>ShouldBroadcast</code> ويضيفه لقائمة انتظار البث:<syntaxhighlight lang="php"> | ||
event(new ShippingStatusUpdated($update)); | event(new ShippingStatusUpdated($update)); | ||
</syntaxhighlight> | |||
فقط للآخرين | ==== فقط للآخرين ==== | ||
عند بناء تطبيق يستعمل تقنية البث، يمكنك تعويض الدالة <code>event</code> بالدالة <code>broadcast</code>. مثل <code>event</code>، يُطلق <code>broadcast</code> الحدث من جهة الخادم للمستمع في جهة العميل<syntaxhighlight lang="php"> | |||
broadcast(new ShippingStatusUpdated($update)); | |||
</syntaxhighlight> | |||
لكن الدالة <code>broadcast</code> توفر أيضًا التابع <code>toOthers</code> الذي يسمح باستثناء المستخدم الحالي من لائحة المستقبلين:<syntaxhighlight lang="php"> | |||
broadcast(new ShippingStatusUpdated($update))->toOthers(); | |||
</syntaxhighlight> | |||
لفهم أفضل متى قد تريد استعمال التابع <code>toOthers</code>، لنتخيل تطبيقا للائحة مهام حيث يمكن للمستخدم صناعة مهمة جديدة بتمرير اسم المهمة. لإنشاء مهمة، يبعث التطبيق طلبًا لنقطة النهاية task/ التي تبث صناعة المهمة وتعيد تمثيل <code>JSON</code> للمهمة الجديدة. يتلقى تطبيق <code>javascript</code> الجواب من نقطة النهاية، يمكنه إضافة المهمة الجديدة للائحته كالآتي<syntaxhighlight lang="php"> | |||
axios.post('/task', task) | |||
.then((response) => { | |||
this.tasks.push(response.data); | |||
}); | |||
</syntaxhighlight> | |||
لكن تذكر أننا نبث أيضًا صناعة المهمة، إذا كان تطبيق JavaScript يستمع للحدث ليضيف المهام الجديدة للائحة المهام، سيكون لديك نفس المهمة مرتين: واحد من نقطة النهاية وواحد من البث. يمكن حل هذا المشكل باستخدام التابع <code>toOthers</code> لإعلام الباث بعدم بث الحدث للمستخدم الحالي. | |||
<u>تنبيه</u>: يجب على الحدث استخدام الخاصية <code>Illuminate\Broadcasting\InteractsWithSockets</code> للاستعمال التابع <code>toOthers</code>. | |||
===== الضبط ===== | |||
عند بدء مثيل Laravel Echo، يُعطى معرّف توصيل (Socket id) للصلة. إذا كنت تستخدم <code>Vue</code> و <code>Axios</code>، يُرفق المعرّف تلقائيًا بكل طلب خارج كعنوان <code>x-socket-ID</code>. ثم عندما تنادي التابع <code>toOthers</code>، يأخذ Laravel المعرّف من العنوان ويأمر الباث بعدن البث لأي صلة تحمل ذلك المعرّف. | |||
إذا كنت لا تستخدم <code>Vue</code> و <code>Axios</code>، ستحتاج لضبط تطبيق JavaScript يدويًا ليُرسل العنوان <code>x-socket-ID</code>. يمكنك استرجاع معرّف التوصيل بالتابع <code>Echo.socketID</code>: | |||
<syntaxhighlight lang="php"> | |||
إذا كنت لا تستخدم Vue و | |||
var socketId = Echo.socketId(); | var socketId = Echo.socketId(); | ||
تلقي البث | </syntaxhighlight> | ||
=== تلقي البث === | |||
تثبيت Laravel echo | تثبيت Laravel echo | ||
Laravel Echo هي مكتبة Javascript تجعل الانخراط في قناة و والإستماع للأحداث أمرًا سهلًا. يمكنك تثبيت Echo عبر منظم الحزم NPM. في هذا المثال، سنثبت أيضًا pusher-js حيث سنستخدم المشغل pusher للبث: | Laravel Echo هي مكتبة Javascript تجعل الانخراط في قناة و والإستماع للأحداث أمرًا سهلًا. يمكنك تثبيت Echo عبر منظم الحزم NPM. في هذا المثال، سنثبت أيضًا pusher-js حيث سنستخدم المشغل pusher للبث: |
مراجعة 20:41، 11 أكتوبر 2018
المقدمة
في العديد من التطبيقات الحديثة، تُستعمل 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;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Get the channels the event should broadcast on.
*
* @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 {
/**
* Create a new channel instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Authenticate the user's access to the channel.
*
* @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
تبني قنوات الحضور (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.
مصادر
صفحة Broadcasting في توثيق Laravel الرسمي.