دفع البيانات إلى العملاء باستخدام
Mercure
نظرة عامة
يُعد بث البيانات في الوقت الفعلي من الخوادم إلى العملاء متطلبًا أساسيًا للعديد من تطبيقات الويب والهواتف الحديثة.
حالات الاستخدام الشائعة:
- إنشاء واجهة مستخدم تتفاعل مباشرة مع التغييرات التي يجريها مستخدمون آخرون
- إشعار المستخدم عند اكتمال مهمة غير متزامنة
- إنشاء تطبيقات المحادثة (Chat)
ما هو Mercure؟
Mercure هو بروتوكول مفتوح المصدر مصمم خصيصًا لنشر التحديثات من الخادم إلى العملاء. وهو بديل حديث وفعال لـ:
- الاستطلاع المبني على المؤقتات (Timer-based polling)
- WebSocket
مميزات Mercure:
- مبني على SSE: يعتمد على Server-Sent Events، مما يجعله مدعومًا في المتصفحات الحديثة
- آلية التفويض: نظام مصادقة مدمج
- إعادة الاتصال التلقائي: مع استرجاع التحديثات المفقودة
- واجهة الحضور (Presence API): لمعرفة المستخدمين المتصلين
- الدفع بدون اتصال: للهواتف الذكية
- الاكتشاف التلقائي: يمكن للعميل اكتشاف التحديثات تلقائيًا
التثبيت
تثبيت حزمة Symfony:
composer require mercure
تشغيل Mercure Hub:
يعتمد Mercure على Hub (موزع مركزي) لإدارة الاتصالات المستمرة. تطبيق Symfony ينشر التحديثات إلى الـ Hub، والذي يبثها للعملاء.
[تطبيق Symfony] --POST--> [Mercure Hub] --SSE--> [العملاء]
الإعدادات
متغيرات البيئة الأساسية:
| المتغير | الوصف |
|---|---|
MERCURE_URL |
عنوان URL المحلي للـ Hub (يستخدمه تطبيق Symfony) |
MERCURE_PUBLIC_URL |
عنوان URL العام (يستخدمه JavaScript في المتصفح) |
MERCURE_JWT_SECRET |
المفتاح السري لتوقيع JWT |
مثال على الإعدادات (YAML):
# config/packages/mercure.yaml
mercure:
hubs:
default:
url: '%env(string:MERCURE_URL)%'
public_url: '%env(string:MERCURE_PUBLIC_URL)%'
jwt:
secret: '%env(string:MERCURE_JWT_SECRET)%'
الاستخدام الأساسي
النشر (Publishing):
namespace App\Controller;
use Symfony\Component\Mercure\HubInterface;
use Symfony\Component\Mercure\Update;
class PublishController extends AbstractController
{
public function publish(HubInterface $hub): Response
{
// إنشاء تحديث جديد
$update = new Update(
'https://example.com/books/1', // الموضوع (Topic)
json_encode(['status' => 'OutOfStock']) // البيانات
);
// نشر التحديث
$hub->publish($update);
return new Response('تم النشر!');
}
}
ملاحظات:
- المعامل الأول (
topic): معرف فريد للمورد (عادة URL أو IRI) - المعامل الثاني: محتوى التحديث (يُفضل JSON أو XML)
الاشتراك (Subscribing):
في قالب Twig:
<script>
const eventSource = new EventSource("{{ mercure('https://example.com/books/1') }}");
eventSource.onmessage = event => {
// يُستدعى في كل مرة يُنشر فيها تحديث
console.log(JSON.parse(event.data));
}
</script>
الاشتراك في مواضيع متعددة:
const eventSource = new EventSource("{{ mercure([
'https://example.com/books/1',
'https://example.com/books/2',
'https://example.com/reviews/{id}' // قالب URI
]) }}");
الاكتشاف (Discovery)
يمكن لتطبيق Symfony إضافة رابط الـ Hub في ترويسة HTTP:
use Symfony\Component\Mercure\Discovery;
class DiscoverController extends AbstractController
{
public function discover(Request $request, Discovery $discovery): JsonResponse
{
// يُضيف: Link: <https://hub.example.com/.well-known/mercure>; rel="mercure"
$discovery->addLink($request);
return $this->json(['@id' => '/books/1']);
}
}
التفويض (Authorization)
التحديثات الخاصة:
لإرسال تحديثات للمستخدمين المصرح لهم فقط:
$update = new Update(
'https://example.com/books/1',
json_encode(['status' => 'OutOfStock']),
true // تحديث خاص
);
الاشتراك في التحديثات الخاصة:
<script>
const eventSource = new EventSource(
"{{ mercure('https://example.com/books/1', { subscribe: 'https://example.com/books/1' }) }}",
{ withCredentials: true } // مهم لإرسال الكوكيز
);
</script>
الاختبار (Testing)
اختبار الوحدات:
use Symfony\Component\Mercure\MockHub;
$hub = new MockHub(
'https://internal/.well-known/mercure',
new StaticTokenProvider('foo'),
function(Update $update): string {
return 'id';
}
);
التكامل مع API Platform
use ApiPlatform\Core\Annotation\ApiResource;
#[ApiResource(mercure: true)] // تفعيل البث التلقائي
#[ORM\Entity]
class Book
{
public string $name = '';
public string $status = '';
}
هذا يُمكّن البث التلقائي للتحديثات عند إنشاء أو تعديل أو حذف أي كتاب.
ملخص
| المفهوم | الشرح |
|---|---|
| Mercure | بروتوكول لدفع البيانات في الوقت الفعلي |
| Hub | خادم وسيط يدير الاتصالات |
| Topic | معرف فريد للمورد المُحدَّث |
| SSE | تقنية المتصفح للاستماع للتحديثات |
| JWT | رمز للمصادقة والتفويض |
المصدر: توثيق سيمفوني الإصدار 6.4
الكاتب عامر مالك محمد
مطور متكامل مع أكثر من سنتين من الخبرة في تطوير PHP الكائني (Symfony) و JavaScript و MySQL. متخصص في حلول التجارة الإلكترونية (Shopware 5/6) وتطوير REST API وأتمتة العمليات في الفرق الرشيقة.
تواصل مع الكاتب