دفع البيانات إلى العملاء باستخدام بروتوكول Mercure

Dec 07, 2025 2 دقيقة قراءة 424 مشاهدة
دفع البيانات إلى العملاء باستخدام بروتوكول Mercure

دفع البيانات إلى العملاء باستخدام

Mercure

نظرة عامة

يُعد بث البيانات في الوقت الفعلي من الخوادم إلى العملاء متطلبًا أساسيًا للعديد من تطبيقات الويب والهواتف الحديثة.

حالات الاستخدام الشائعة:

  • إنشاء واجهة مستخدم تتفاعل مباشرة مع التغييرات التي يجريها مستخدمون آخرون
  • إشعار المستخدم عند اكتمال مهمة غير متزامنة
  • إنشاء تطبيقات المحادثة (Chat)

ما هو Mercure؟

Mercure هو بروتوكول مفتوح المصدر مصمم خصيصًا لنشر التحديثات من الخادم إلى العملاء. وهو بديل حديث وفعال لـ:

  • الاستطلاع المبني على المؤقتات (Timer-based polling)
  • WebSocket

مميزات Mercure:

  1. مبني على SSE: يعتمد على Server-Sent Events، مما يجعله مدعومًا في المتصفحات الحديثة
  2. آلية التفويض: نظام مصادقة مدمج
  3. إعادة الاتصال التلقائي: مع استرجاع التحديثات المفقودة
  4. واجهة الحضور (Presence API): لمعرفة المستخدمين المتصلين
  5. الدفع بدون اتصال: للهواتف الذكية
  6. الاكتشاف التلقائي: يمكن للعميل اكتشاف التحديثات تلقائيًا

التثبيت

تثبيت حزمة 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

شارك هذا المنشور

AM

الكاتب عامر مالك محمد

مطور متكامل مع أكثر من سنتين من الخبرة في تطوير PHP الكائني (Symfony) و JavaScript و MySQL. متخصص في حلول التجارة الإلكترونية (Shopware 5/6) وتطوير REST API وأتمتة العمليات في الفرق الرشيقة.

تواصل مع الكاتب