خادوم دردشة محلية كتبته بـNode.js/Express/Socket.IO/React/Redux/Webpack
في الفترة الماضية كنت أعمل على تطبيق يجمع ما تعلمته طيلة الشهور الفائتة (React + Redux + Webpack، ثلاث مكونات أخذت تتصاعد شعبيّتها مؤخّرًا)، فقمت بكتابة خادوم وعميل دردشة بشكل مشابه لـWhatsApp Web وبواجهة مصممة وفق Material Design، يعمل ضمن المتصفحات على الشبكة المحلية، حيث يمكن لأي جهاز على الشبكة إنشاء الخادوم ثم يمكن للأجهزة الأخرى الانضمام إليه وبدء الدردشة سويّة عبر WebSockets. يتم اكتشاف الخواديم تلقائيًّا باستخدام بروتوكول Zeroconf/Bonjour، وتستخدم Socket.IO لنقل رسائل الدردشة.
بالإضافة إلى ما سبق، استخدمت:
Babel طبعًا
Reselect لـRedux
Promsie middleware لـRedux
CSS Modules
ESLint
VSCode
فيديو يستعرض المشروع:
الخطوات القادمة:
تشفير الرسائل باستخدام asymmetric key encryption باستخدام واجهة التشفير WebCrypto API في المتصفحات الحديثة، يتم تطبيق التشفير بشكل شفاف (transparent) عن طريق middleware لـRedux يشفر الرسائل الصادرة ويفك تشفير الرسائل الواردة ويمررها لـلـstore.
تحسين المظهر (المشروع ليس إلا proof of concept)
المصدر متوفر على GitHub:
React ليست إطار عمل، وهي فكرة يكررها كثيرًا أنصارها والعاملون على تطويرها، React مسؤولة فقط عن عرض العناصر في الصفحة. ما زلت تحتاج إلى طريقة لإدارة المعلومات في الصفحة، هناك أساليب مختلفة ذلك، لكن مطوّري React ينصحون باعتماد بنية Flux، أو انسياب البيانات باتجاه واحد. معنى ذلك أن المُكوّنات غير مرتبطة ببعضها، ولا تقوم بتعديل البيانات مباشرة، بل تستقي البيانات من مصدر أعلى منها، وإذا أرادت تعديل البيانات فهي تُرسل "حدثًا action" يصف التغيير المطلوب إلى "مستودع store" من مستودعات البيانات. يقوم المستودع بتعديل البيانات بالشكل المطلوب، ثمّ تُعيد React رسم كل المُكوّنات المُعتمدة على الجزء المتغيّر من البيانات. فائدة ذلك هو أنّ المُكوّنات لا تحتاج إلى أن تعلم إن كانت مكوّنات أخرى في الصّفحة تعتمد على البيانات الّتي تعدّلها، بل فقط تهتمّ بنفسها وتعبّر عن رغبتها بتعديل البيانات في المصدر الأعلى، وهذا يؤدّي إلى تدفّق "flow" البيانات من أعلى إلى أسفل فقط، وليس باتّجاهين (two-way data binding) أي بين المكوّنات نفسها كما في Angular.
Redux تذهب أبعد من ذلك، وقد أصبحت المعيار الذّهبي لبنية Flux، لأنّها تقوم بإنشاء مستودع وحيد يحتوي كلّ بيانات التطبيق، وتقوم المكوّنات بإرسال حدث التّغيير إلى هذا المستودع الّذي يقوم عندها استدعاء وظيفة تستقبل النسخة السابقة من المستودع، وتُعيد نسخة جديدة، وهكذا في كلّ تغيير. معنى ذلك أنّ وظيفة التّغيير (التي تُسمى reducer) هي وظيفة صافية (pure function) لا تعلم شيئًا عن برنامجك، بل فقط تأخذ الحالة السابقة والحدث الحالي، وتُعيد حالة جديدة.
بساطة هذه البنية هي نقطة القوة في Redux، وهي التي تسمح لتطبيقك بأن يكون قابلًا للاختبار بسهولة (unit tests)، كون المكوّنات تستقي البيانات من مصدر أعلى، وتعبّر فقط عن رغبتها بتعديلها، ولا تقوم بتعديلها مباشرة، وهذا يجعل كل مكوّن قابلًا للاختبار بصورة منفصلة، كما أنّه يسهل اختبار وظيفة reducer، لأنّها لا تعلم شيئًا عن التطبيق، بل تحتاج فقط الحدث والحالة الحالية، لتعطيك حالة جديدة.
هناك دورتان لـDan Abramov كاتب Redux، متوفّرتان مجانًا على Egghead.io، أنصح بهما بشدّة:
التعليقات