المرحلة الثالثة: دمج Presence Channel و Private Channel لبناء نظام دردشة متكامل

مقدمة

في المرحلة الأولى قمنا ببناء طبقة الاتصال مع خادم الوقت الحقيقي وتجهيز البنية الأساسية للتطبيق.

وفي المرحلة الثانية استخدمنا Presence Channel لمتابعة المستخدمين المتصلين وإدارة حالة الحضور داخل الغرفة.

الآن وصلنا إلى المرحلة الأخيرة، حيث سنقوم بدمج النوعين معاً لبناء نظام دردشة متكامل يوفر:

  • معرفة المستخدمين المتصلين.
  • إرسال الرسائل بشكل آمن.
  • استقبال الرسائل لحظياً.
  • تحديث واجهة المستخدم مباشرة.
  • ربط الرسائل بالمستخدمين الحقيقيين داخل النظام.

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


لماذا نستخدم قناتين مختلفتين؟

يميل بعض المطورين إلى إرسال كل شيء عبر قناة واحدة، لكن مع توسع التطبيق يصبح هذا الأسلوب صعب الإدارة.

لهذا تم تقسيم المسؤوليات كالتالي:

الوظيفة نوع القناة
معرفة المتصلين Presence Channel
دخول المستخدمين وخروجهم Presence Channel
إرسال الرسائل Private Channel
استقبال الرسائل Private Channel
حماية المحادثات Private Channel

بهذا الشكل يؤدي كل نوع من القنوات مهمة محددة بوضوح.


البنية النهائية للتطبيق

بعد اكتمال جميع المراحل أصبحت مكونات المشروع تعمل معاً بالشكل التالي:

Flutter Application
        │
        ▼
ChatController
        │
        ▼
RealtimeService
        │
 ┌──────┴──────┐
 │             │
 ▼             ▼
Presence     Private
Channel      Channel
 │             │
 ▼             ▼
Users       Messages
Status      Exchange

يتولى RealtimeService إدارة الاتصال بالقناتين في الوقت نفسه، بينما يقوم ChatController بمعالجة البيانات القادمة منهما وتحديث واجهة المستخدم.


دورة عمل المستخدم داخل التطبيق

عند فتح شاشة المحادثة يتم تنفيذ التسلسل التالي:

User Login
     │
     ▼
Connect WebSocket
     │
     ▼
Join Presence Channel
     │
     ▼
Receive Active Users
     │
     ▼
Join Private Channel
     │
     ▼
Send & Receive Messages

وبذلك يصبح المستخدم جزءاً من نظام الحضور ونظام الرسائل في آن واحد.


إنشاء القناة الخاصة

بعد نجاح الاتصال والانضمام إلى Presence Channel يتم الاشتراك في Private Channel الخاصة بالمحادثة.

تتميز القنوات الخاصة بأنها:

  • تتطلب مصادقة المستخدم.
  • لا تسمح بالوصول غير المصرح به.
  • تحمي محتوى الرسائل.
  • تضمن وصول الأحداث للمستخدمين المصرح لهم فقط.

ولهذا تعتبر الخيار الأمثل لنقل الرسائل بين المستخدمين.


إرسال الرسائل

عند كتابة المستخدم رسالة جديدة تحدث الخطوات التالية:

  1. إدخال نص الرسالة.
  2. استدعاء ChatController.
  3. إرسال الطلب إلى Laravel API.
  4. إنشاء حدث بث جديد.
  5. نشر الحدث عبر Private Channel.
  6. وصول الرسالة لجميع المشتركين بالقناة.

تتم هذه العملية خلال أجزاء من الثانية.


هيكل الرسالة المرسلة

يعتمد التطبيق على بنية موحدة للرسائل تسهل التعامل معها في جميع أجزاء النظام.

مثال على البيانات المرسلة:

{
  "message": "مرحباً بالجميع",
  "user": {
    "id": 1,
    "name": "Mustafa",
    "email": "user@example.com"
  }
}

تحتوي الرسالة على:

  • نص الرسالة.
  • بيانات صاحب الرسالة.
  • معلومات كافية لتحديث واجهة المستخدم فوراً.

استقبال الرسائل

بعد وصول الحدث من الخادم يقوم RealtimeService بالتقاطه وإرساله إلى ChatController.

يقوم ChatController عندها بـ:

  1. تحليل البيانات المستلمة.
  2. استخراج الرسالة.
  3. استخراج بيانات المرسل.
  4. إضافة الرسالة إلى القائمة المحلية.
  5. تحديث واجهة المستخدم.

وبذلك تظهر الرسالة فوراً دون الحاجة إلى إعادة تحميل الصفحة أو تنفيذ طلب جديد.


ربط الرسائل بالمستخدمين المتصلين

هنا تظهر أهمية دمج Presence Channel مع Private Channel.

فعند وصول رسالة جديدة يمكن للتطبيق:

  • معرفة صاحب الرسالة.
  • معرفة ما إذا كان ما يزال متصلاً.
  • عرض اسمه الحقيقي.
  • تحديث حالته داخل المحادثة.

وبذلك تصبح الرسائل مرتبطة مباشرة بقائمة المستخدمين النشطين داخل الغرفة.


تحديث واجهة المحادثة لحظياً

عند استقبال رسالة جديدة يتم تنفيذ تحديث فوري للواجهة.

تشمل عملية التحديث:

  • إضافة الرسالة الجديدة.
  • تحديث آخر نشاط.
  • تحريك قائمة الرسائل للأسفل.
  • إعادة رسم العناصر المتأثرة فقط.

هذا الأسلوب يضمن تجربة استخدام سلسة حتى مع زيادة عدد الرسائل.


معالجة حالات الاتصال

في البيئات الحقيقية قد يحدث:

  • انقطاع الإنترنت.
  • إعادة تشغيل الخادم.
  • انتهاء جلسة المستخدم.
  • فقدان الاتصال المؤقت.

لذلك يجب أن تتعامل طبقة الوقت الحقيقي مع:

  • إعادة الاتصال تلقائياً.
  • إعادة الاشتراك بالقنوات.
  • استعادة حالة الحضور.
  • متابعة استقبال الرسائل دون تدخل المستخدم.

وجود هذه المعالجة يجعل التطبيق أكثر استقراراً واعتمادية.


الفوائد التي تحققها هذه البنية

يوفر هذا التصميم مجموعة من المزايا المهمة:

الأداء

يتم إرسال البيانات فقط عند الحاجة دون تنفيذ طلبات متكررة للخادم.

الأمان

تعتمد الرسائل على Private Channels المحمية بالمصادقة.

القابلية للتوسع

يمكن إضافة غرف جديدة أو أنواع مختلفة من المحادثات بسهولة.

سهولة الصيانة

تم فصل الحضور عن الرسائل مما يجعل الكود أكثر تنظيماً.

تجربة المستخدم

تصل الرسائل وتظهر حالة المستخدمين بشكل فوري.


النتيجة النهائية

بعد إكمال المراحل الثلاث أصبح لدينا نظام دردشة متكامل يعتمد على خدمات الوقت الحقيقي في HosteDay.

يتضمن النظام:

  • اتصال WebSocket دائم.
  • إدارة كاملة للمستخدمين المتصلين.
  • قنوات حضور لمتابعة حالة الأعضاء.
  • قنوات خاصة لتبادل الرسائل.
  • تحديث لحظي للواجهة.
  • حماية للرسائل عبر المصادقة.
  • بنية قابلة للتوسع والتطوير مستقبلاً.

بهذا نكون قد أنشأنا تطبيق دردشة حديث يعتمد على الدمج بين Presence Channels و Private Channels، ويوفر تجربة تواصل فورية وآمنة يمكن البناء عليها لإضافة ميزات أكثر تقدماً مثل المجموعات، الإشعارات المباشرة، مؤشرات الكتابة، الرسائل المقروءة، ومشاركة الملفات.