المرحلة الأولى: تهيئة نظام الوقت الحقيقي وبناء طبقة الاتصال
مقدمة
تعتمد تطبيقات الدردشة الحديثة على نقل البيانات بشكل لحظي بين المستخدمين دون الحاجة إلى تحديث الشاشة أو تنفيذ طلبات متكررة للخادم. توفر منصة HosteDay هذه الإمكانية من خلال خدمة الوقت الحقيقي المبنية فوق بروتوكول WebSocket، مما يسمح للتطبيقات باستقبال الأحداث فور حدوثها.
في هذه السلسلة سنقوم ببناء تطبيق دردشة متكامل باستخدام Flutter و Laravel مع الاعتماد على نوعين من القنوات:
- Presence Channel لمعرفة المستخدمين المتصلين.
- Private Channel لتبادل الرسائل الخاصة بشكل آمن.
قبل استخدام أي من هذين النوعين يجب أولاً إنشاء طبقة اتصال مستقرة مع خادم الوقت الحقيقي.
البنية العامة للمشروع
تم تنظيم المشروع وفق بنية Feature-Based Architecture لتسهيل التوسع والصيانة مستقبلاً.
lib/
├── core
│ └── routes
│ ├── app_routes.dart
│ └── auth_middleware.dart
│
├── features
│ ├── auth
│ │ ├── controllers
│ │ │ └── auth_controller.dart
│ │ ├── pages
│ │ │ └── auth_page.dart
│ │ └── providers
│ │ └── auth_provider.dart
│ │
│ └── chat
│ ├── controllers
│ │ └── chat_controller.dart
│ ├── pages
│ │ └── chat_page.dart
│ ├── providers
│ │ └── realtime_provider.dart
│ └── services
│ └── realtime_service.dart
│
└── main.dart
تم فصل منطق الاتصال عن واجهات المستخدم بحيث تكون جميع عمليات الاتصال وإدارة القنوات داخل خدمة مستقلة يمكن إعادة استخدامها في أي جزء من التطبيق.
مسؤولية كل طبقة
RealtimeService
يعتبر القلب الحقيقي للنظام.
مسؤول عن:
- إنشاء اتصال WebSocket.
- إدارة حالة الاتصال.
- الاشتراك بالقنوات.
- الاستماع للأحداث.
- إغلاق الاتصال عند الحاجة.
وجود هذه الطبقة يمنع تكرار الكود داخل الصفحات أو Controllers.
RealtimeProvider
طبقة وسيطة تتعامل مع واجهات Laravel API.
مسؤوليتها:
- إرسال الرسائل للخادم.
- تنفيذ الطلبات المتعلقة بالأحداث اللحظية.
- التعامل مع الاستجابات.
- تحويل البيانات إلى نماذج قابلة للاستخدام داخل التطبيق.
ChatController
يتولى الربط بين الواجهة وخدمة الوقت الحقيقي.
مسؤول عن:
- تشغيل الاتصال عند فتح شاشة المحادثة.
- الاشتراك بالقنوات المطلوبة.
- استقبال الرسائل الجديدة.
- تحديث واجهة المستخدم.
إنشاء الاتصال مع الخادم
يعتمد التطبيق على مكتبة Pusher Compatible Client والتي تتوافق مباشرة مع خدمة الوقت الحقيقي في HosteDay.
عند تشغيل شاشة المحادثة يتم تنفيذ الخطوات التالية:
- قراءة رمز الوصول (Access Token).
- إنشاء اتصال آمن عبر WSS.
- فتح جلسة WebSocket.
- انتظار تأكيد الاتصال من الخادم.
- الاشتراك بالقنوات المطلوبة.
بعد نجاح هذه العملية يصبح التطبيق جاهزاً لاستقبال الأحداث فور حدوثها.
المصادقة Authentication
قبل السماح للمستخدم بالاشتراك في أي قناة محمية يجب التأكد من هويته.
تتم العملية بالشكل التالي:
- تسجيل دخول المستخدم.
- الحصول على Sanctum Token.
- تخزين الرمز محلياً.
- استخدام الرمز عند طلب الاشتراك بالقنوات.
هذا الأسلوب يضمن أن المستخدمين المصرح لهم فقط يمكنهم الوصول إلى البيانات اللحظية.
دورة حياة الاتصال
يمر الاتصال بعدة مراحل:
Application Start
│
▼
User Login
│
▼
Store Access Token
│
▼
Connect WebSocket
│
▼
Connection Established
│
▼
Subscribe Channels
│
▼
Listen For Events
هذه الدورة تمثل الأساس الذي ستعتمد عليه جميع المراحل القادمة.
اختبار نجاح الاتصال
يمكن التأكد من نجاح الاتصال من خلال مراقبة الحالات التالية:
- تم فتح اتصال WebSocket بنجاح.
- استلام رسالة Connected من الخادم.
- نجاح الاشتراك في القناة.
- عدم ظهور أخطاء Authentication.
عند تحقق هذه النقاط يصبح النظام جاهزاً للانتقال إلى الخطوة التالية وهي إدارة المستخدمين المتصلين عبر Presence Channels.
ماذا سنبني في المرحلة القادمة؟
بعد إنشاء الاتصال الأساسي سننتقل إلى استخدام Presence Channels لعرض المستخدمين المتصلين حالياً داخل التطبيق.
سنتعلم كيفية:
- معرفة من دخل إلى الغرفة.
- معرفة من غادر الغرفة.
- الحصول على قائمة المستخدمين المتصلين.
- تحديث الواجهة لحظياً عند تغير حالة الاتصال.
وهي الخطوة التي ستحول الاتصال الخام الذي أنشأناه في هذه المرحلة إلى تجربة تفاعلية حقيقية للمستخدمين.