التصاميم · فصل ١٢

تصميم Chat System

WebSocket · long polling · message store · presence
🎯 الهدف: الرسالة توصل في الاتجاهين فورًا، وتتخزن، وتوصل كمان لو اليوزر قافل الأبلكيشن.

السيرفر يوصل للـ client إزاي؟

الـ HTTP عادةً الـ client هو اللي بيبدأ. طب إزاي السيرفر يبعت رسالة جت لسه؟

الطريقةالفكرةالحكم
Pollingالـ client يسأل كل شوية “فيه جديد؟”هدر، وأغلب الردود فاضية
Long Pollingيفضل الكونكشن مفتوح لحد ما يجي جديد أو timeoutأحسن، بس صعب مع load balancer ومش دايمًا يعرف إن اليوزر خرج
WebSocketكونكشن مستمر في الاتجاهينده الاختيار للإرسال والاستقبال

الـ WebSocket هو اللي بنبني عليه الشات. تسجيل الدخول والبروفايل والجروبات يفضلوا HTTP عادي ورا load balancer.

المعمارية

Stateless

تسجيل دخول، بروفايل، جروبات — HTTP عادي ورا load balancer. أي سيرفر يخدم أي ريكوست.

Stateful

سيرفرات الشات: كل client ماسك WebSocket مع سيرفر معيّن. Service discovery (زي Zookeeper) بيختارلك أنسب سيرفر.

تخزين الرسايل: حجم ضخم، والوصول غالبًا للرسايل الجديدة. Key-value store زي HBase أو Cassandra مناسب.

الـ message ID لازم يكون فريد ومرتب بالوقت (Snowflake، أو sequence محلي لكل محادثة).

ولو اليوزر offline: push notification.

التدفق

لو B أونلاين: Chat Server 2 يوصّله الرسالة على الـ WebSocket. لو أوفلاين: Push Notification.

  • كذا جهاز: كل جهاز فاكر cur_max_message_id وبيجيب أي رسالة أحدث منه.
  • جروب صغير: الرسالة تتنسخ في “صندوق” كل عضو — بسيط لحد عدد أعضاء معيّن.
  • Online presence: Heartbeat كل كام ثانية. لو انقطع فترة يبقى offline، عشان النت الضعيف مايخليش الحالة تتقلب كل ثانية. التحديث بيوصل للصحاب عن طريق pub/sub.

Checklist الشات

🧠 اختبر نفسك
١) ليه polling وحش للشات؟
اليوزر بيسأل كل شوية وأغلب الردود فاضية، فبتضيع سيرفرات وبطارية.
٢) ليه سيرفر الشات stateful والبروفايل stateless؟
لأن الـ WebSocket كونكشن طويل مربوط بسيرفر معيّن. البروفايل ريكوست قصير أي سيرفر يرده.
٣) جهازين لنفس اليوزر. إزاي التاني يلحق الرسايل؟
كل جهاز فاكر آخر message ID شافه، وبيجيب اللي أحدث منه.
٤) ليه الـ presence مستناش انقطاع ثانية واحدة؟
عشان النت الضعيف مايقلّبش الحالة online/offline كل لحظة. بنستنى فترة heartbeat.