لتطوير وتجميع MEGAchat ، نستخدم بشكل أساسي CMake كأداة لتكوين المشروع عبر الأنظمة الأساسية. نستخدم أيضًا VCPKG لإدارة التبعيات المطلوبة لإنشاء MEGAchat في معظم الأنظمة الأساسية: Windows وMacOS وLinux.
للحصول على تفاصيل حول أدوات البناء الضرورية لكل نظام تشغيل، قم بمراجعة فصل أدوات البناء في مستودع MEGA SDK.
مزيد من المعلومات حول تجميع WebRTC Android في WebRTC لنظام Android
يتطلب MEGAchat بعض التبعيات للعمل. يتم تنزيل معظمها تلقائيًا وإنشاؤها باستخدام VCPKG أثناء مرحلة التكوين.
بالنسبة لنظام Linux، هناك حاجة إلى بعض المكتبات الإضافية في النظام حتى يتمكن VCPKG من بناء التبعيات. بالنسبة للتوزيعات المبنية على دبيان، يمكنك تثبيت المكتبات الضرورية باستخدام الأمر التالي:
sudo apt install python3-pkg-resources libglib2.0-dev libgtk-3-dev libasound2-dev libpulse-dev
قد تختلف أسماء الحزم باختلاف توزيعات Linux، ولكن يجب أن يتم إنشاؤها بنجاح باستخدام الحزم التي توفر نفس المكتبات.
يمكنك إلقاء نظرة على المجموعة الكاملة من التبعيات في ملف vcpkg.json الموجود في جذر المستودع.
يحتاج MEGAchat أيضًا إلى مكتبة MEGA SDK. توجد تعليمات لاحقًا في هذا المستند حول كيفية استخدامه مع MEGAchat . يتم تحميل مشروع MEGA SDK تلقائيًا بواسطة MEGAchat CMake، لذا ما عليك سوى استنساخه في المسار المتوقع.
هناك تبعية اختيارية إضافية واحدة فقط يجب تثبيتها في النظام: Qt Framework. من الضروري فقط إنشاء تطبيق Qt example ولكنه غير مطلوب للاختبارات أو مثال CLI أو المكتبة نفسها.
أولاً، قم بإعداد دليل من اختيارك للعمل مع MEGAchat . سيتم استخدام الدليل mega
كدليل مساحة العمل في الأمثلة الموجودة في هذا المستند.
mkdir mega
cd mega
بعد إعداد الدليل، قم باستنساخ مستودع MEGAchat للحصول على كود مصدر MEGAchat .
git clone https://github.com/meganz/MEGAchat
نظرًا لأن MEGAchat يتطلب MEGA SDK للعمل، فقم باستنساخ MEGA SDK في المسار المتوقع.
git clone https://github.com/meganz/sdk MEGAchat/third-party/mega
وأخيرًا، قم باستنساخ مستودع VCPKG بجوار مجلد MEGAchat . إذا كنت تستخدم VCPKG بالفعل ولديك نسخة محلية من المستودع، فيمكنك تخطي هذه الخطوة واستخدام VCPKG الموجود على نظامك.
git clone https://github.com/microsoft/vcpkg
الإرشادات التالية مخصصة لتكوين المشروع من واجهة سطر الأوامر (CLI)، ولكن يجب أن يكون cmake-gui أو أي محرر أو IDE متوافق مع CMake مناسبًا إذا تم تكوين نفس معلمات CMake.
تم تكوين MEGAchat مثل أي مشروع CMake عادي آخر. المعلمة الوحيدة المطلوبة دائمًا هي دليل VCPKG لإدارة تبعيات الطرف الثالث. تم إنشاء تبعية MEGA SDK كجزء من إنشاء MEGAchat .
لتكوين MEGAchat ، من مساحة العمل (دليل mega
)، قم بتشغيل CMake:
cmake -DVCPKG_ROOT=vcpkg -DCMAKE_BUILD_TYPE=Debug -S MEGAchat -B build_dir
ملاحظة 1 : قد لا تكون هناك حاجة إلى -DCMAKE_BUILD_TYPE=<Debug|Release>
للمولدات متعددة التكوين، مثل Visual Studio.
ملاحظة 2: إذا تم تثبيت Qt Framework على نظامك ولكن فشل CMake في اكتشافه، فيمكنك إضافة -DCMAKE_PREFIX_PATH=</path/to/qt/install/dir>
حتى يتمكن CMake من تحديد موقعه. إذا لم يتم تثبيت Qt وكنت تفضل عدم تثبيته، فيمكنك تعطيل تطبيق Qt example عن طريق الإعداد -DENABLE_CHATLIB_QTAPP=OFF
. سيستمر إنشاء المكتبة ومثال CLI والاختبارات.
في الأمر cmake أعلاه، تم استخدام المسارات النسبية للتبسيط. إذا كنت تريد تغيير موقع VCPKG أو MEGAchat أو دليل البناء، فما عليك سوى توفير مسار نسبي أو مطلق صالح لأي منها.
أثناء تكوين المشروع، سيقوم VCPKG ببناء وتكوين المكتبات اللازمة للنظام الأساسي. قد يستغرق الأمر بعض الوقت في التشغيل الأول، ولكن بمجرد إنشاء المكتبات، سيقوم VCPKG باسترجاعها من ذاكرة التخزين المؤقت الثنائية.
يمكن تكوين MEGAchat بخيارات مختلفة، يمكن العثور على بعضها في ملف chatlib_options.cmake. خيارات إدارة الأمثلة والاختبارات موجودة في CMakeLists.txt.
بمجرد تكوين MEGAchat ، ما عليك سوى إنشاء المشروع الكامل:
cmake --build build_dir
يمكنك تحديد --target=<target>
مثل CHATlib
أو megaclc
، أو فقط اترك الأمر كما هو لإنشاء جميع العلامات. بالإضافة إلى ذلك، يمكن إضافة -j <N>
أو --parallel <N>
لإدارة التزامن وتسريع الإنشاء.
بمجرد الانتهاء من البناء، ستكون الثنائيات متاحة في build_dir
، الذي تم تحديده في أمر تكوين CMake.
لتجريد تعقيد التعليمات البرمجية، توفر MEGAchat طبقة وسيطة تمكنك من إنشاء تطبيقات جديدة بسرعة.
الوثائق متاحة على src/ MEGAchat api.h
يشبه نموذج ترابط MEGAchat نموذج ترابط جافا سكريبت - كل شيء يعمل في مؤشر الترابط الرئيسي (GUI)، ولا يُسمح بالحظر مطلقًا، والأحداث الخارجية (الشبكة، والمؤقتات، وما إلى ذلك، وأحداث webrtc، وما إلى ذلك) تؤدي إلى عمليات رد اتصال على الموضوع الرئيسي. لكي ينجح هذا الأمر، يجب أن يكون MEGAchat قادرًا على التفاعل مع حلقة أحداث التطبيق - وعادةً ما تكون هذه حلقة حدث/رسالة لإطار عمل واجهة المستخدم الرسومية في حالة تطبيق واجهة المستخدم الرسومية، أو حلقة رسالة مخصصة في حالة تطبيق وحدة التحكم. نظرًا لأن حلقة الرسائل هذه خاصة بالنظام الأساسي، تقع على عاتق مطور التطبيق مسؤولية تنفيذ الواجهة بينها وبين MEGAchat . قد يبدو هذا أكثر تعقيدًا مما هو عليه في الواقع - فالواجهة تتكون من جزأين. جزء واحد هو تنفيذ وظيفة megaPostMessageToGui(void*)
، التي تنشر مؤشر void*
غير شفاف إلى حلقة رسالة التطبيق. يتم استدعاء هذه الوظيفة عادةً بواسطة سلاسل رسائل أخرى غير الخيط الرئيسي، ولكن يمكن أيضًا استدعاؤها بواسطة سلاسل رسائل واجهة المستخدم الرسومية نفسها. الجزء الآخر هو الكود الموجود في حلقة رسائل التطبيق الذي يتعرف على هذا النوع من الرسائل ويمررها مرة أخرى إلى MEGAchat ، عن طريق استدعاء megaProcessMessage(void*)
بنفس المؤشر - هذه المرة في سياق مؤشر الترابط الرئيسي (GUI). تم تنفيذ كل هذا في /src/base/gcm.h
و /src/base/gcm.hpp
. تحتوي هذه الملفات على وثائق مفصلة. مثال على تنفيذ ذلك على نظام التشغيل Windows هو: megaPostMessageToGui(void*)
سوف يقوم بتنفيذ PostMessage()
مع نوع رسالة مستخدم، void*
باعتباره lParam أو wParam للرسالة، وفي بيان switch
معالجة الحدث، سيكون هناك إدخال لهذا النوع من الرسائل، والحصول على مؤشر void*
عن طريق إرسال lParam أو wParam للرسالة، وتمريره إلى megaProcessMessage(void*)
.
يعتمد MEGAchat على libuv، الذي يعمل في مؤشر ترابط خاص به، لمراقبة مآخذ توصيل متعددة لأحداث الإدخال/الإخراج الأولية، ولتنفيذ المؤقتات. ويعتمد أيضًا على وظائف الإدخال/الإخراج ذات المستوى الأعلى لـ libuv مثل دقة DNS ومآخذ SSL. يتم تنفيذ طبقة رقيقة أعلى libuv، تسمى "services" ( /src/base/?services*.*
) أعلى libuv وGCM للحصول على واجهات برمجة التطبيقات C++11 غير المتزامنة البسيطة والمشابهة لجافا سكريبت للمؤقتات ( src/base/timer.h
)، دقة DNS ( /src/base/services-dns.hpp
)، عميل http ( /src/base/services-http.hpp
). تم تصميم هذه الطبقة في الأصل لتحتوي على مكون ذي مستوى أدنى مع واجهة C عادية (ملفات cservices*.cpp/h
)، بحيث يمكن استخدام الخدمات بواسطة العديد من مكتبات الارتباط الحيوي (DLL) المبنية باستخدام مترجمين مختلفين، ورأس C عالي المستوى فقط. طبقة ++11 التي تمثل الواجهة الأمامية وتحتوي على واجهة برمجة التطبيقات العامة - وهي ملفات .hpp.
تستخدم جميع مكتبات الشبكة في MEGAchat (libcurl) libuv لتشغيل الشبكة والمؤقتات (تستخدم مكتبات C libuv مباشرة، ويستخدم كود C++ طبقة C++ 11، أي timers.hpp
). يوصى بشدة أن يقوم مستخدم SDK أيضًا بنفس الشيء، على الرغم من أنه من الممكن على سبيل المثال أن يكون لديه مؤشر ترابط عامل مخصص يحظر على مأخذ توصيل، وينشر الأحداث إلى مؤشر ترابط واجهة المستخدم الرسومية عبر GCM.
نمط الاستخدام هو كما يلي: يتم تسجيل رد الاتصال لحدث معين (حدث الإدخال / الإخراج للمأخذ، والمؤقت، وما إلى ذلك)، ويتم استدعاء رد الاتصال هذا بواسطة مؤشر ترابط libuv عند وقوع الحدث. إذا كان من الممكن أن ينتشر الحدث خارج المكتبة التي تم استدعاء رد الاتصال بها، وخاصة إلى واجهة المستخدم الرسومية، ففي مرحلة ما، يجب تنظيم معالجة الحدث إلى مؤشر ترابط واجهة المستخدم الرسومية، باستخدام آلية GCM. ومع ذلك، إذا كان الحدث داخليًا ولم ينتشر أبدًا خارج المكتبة، فيمكن التعامل معه مباشرةً في سياق خيط libuv (شريطة ألا يمنعه أبدًا). يؤدي هذا إلى حفظ تكلفة الأداء لتنظيمه إلى مؤشر ترابط واجهة المستخدم الرسومية، ويوصى به إذا حدث الحدث بتردد عالٍ، على سبيل المثال، حدث مجموعة بيانات واردة يحتاج فقط إلى البيانات الملحقة بمخزن مؤقت. عند اكتمال النقل، يمكن تنظيم حدث الإكمال على مؤشر ترابط واجهة المستخدم الرسومية مرة واحدة لكل عملية نقل، مما يجمع بين مزايا كلا الطريقتين.
لدى MEGAchat إمكانية تسجيل متقدمة تدعم تسجيل الملفات ووحدة التحكم بالألوان، وتدوير ملف السجل، وقنوات سجل متعددة، كل منها بمستوى سجل فردي. يتم تكوين مستويات السجل في وقت التشغيل (عند بدء التشغيل)، وليس في وقت الترجمة (أي ليس عن طريق تعطيل وحدات ماكرو السجل). يسمح هذا للتطبيق المدمج في الإصدار بتمكين تسجيل التصحيح الكامل لأي قنوات. يتم تعريف قنوات السجل وتكوينها افتراضيًا في src/base/loggerChannelConfig.h. يحتوي الملف على وثائق مفصلة. للراحة، عادةً ما يتم تعريف وحدات ماكرو التسجيل المخصصة لكل قناة في الكود الذي يستخدمها - راجع وحدات الماكرو XXX_LOG_DEBUG/WARN/ERROR في karereCommon.h للحصول على أمثلة. يتمتع مستخدم SDK بالحرية في إنشاء قنوات سجل إضافية إذا لزم الأمر. تم تعريف قناة سجل واجهة المستخدم الرسومية بالفعل. يمكن تجاوز تكوين قناة السجل في وقت التشغيل بواسطة متغير بيئة KRLOG. تنسيقه هو كما يلي:
KRLOG=<chan name>=<log level>,<chan name2>=<log level2>...
مستويات السجل هي "إيقاف"، و"خطأ"، و"تحذير"، و"معلومات"، و"مطول"، و"تصحيح"، و"تصحيح".
يوجد اسم قناة خاص واحد - "الكل". يؤدي تعيين مستوى السجل لهذه القناة إلى تعيين مستويات السجل لجميع القنوات. يتيح ذلك على سبيل المثال إسكات جميع القنوات بسهولة باستثناء قناة واحدة (أو عدد قليل منها)، وذلك من خلال:
KRLOG=all=warn,mychannel=debug,myotherchannel=info
يمكن تكوين نفس القناة عدة مرات، وسيكون الإعداد الأخير فقط فعالاً، مما يجعل الحيلة المذكورة أعلاه ممكنة.
يتطلب MEGAchat تعريف الوظيفة karere::getAppDir()
بواسطة التطبيق في وقت الترجمة، لمعرفة مكان إنشاء ملف السجل وبدء التسجيل في أقرب وقت ممكن، قبل إدخال main()
. إذا تم إنشاء MEGAchat كمكتبة ثابتة، فهذه ليست مشكلة. في حالة lib الديناميكي، يجب أن تكون هذه الوظيفة رمزًا ضعيفًا، حتى يتمكن MEGAchat نفسه من التجميع دون تنفيذ الوظيفة، ويتم ربط التنفيذ عند تحميل MEGAchat lib المشترك عند بدء تشغيل التطبيق. الرموز الضعيفة ليست قابلة للنقل عبر المترجمين، وقد يكون هذا مشكلة. ومع ذلك فهي مدعومة من قبل كل من دول مجلس التعاون الخليجي و clang. إذا لم يتم دعم أي رموز ضعيفة، فيجب إنشاء karer على هيئة lib ثابت.
base/promise.h
ومثال الاستخدام على سبيل المثال في /src/test-promise.cpp
setTimeout()
و setInterval()
في /src/base/timers.hpp
marshallCall()
بتنظيم استدعاءات lambda من مؤشر ترابط عامل إلى مؤشر ترابط واجهة المستخدم الرسومية. يمكن رؤية أمثلة الاستخدام على سبيل المثال في /src/webrtcAdapter.h
وفي العديد من الأماكن المختلفة. لا ينبغي أن تكون هذه الآلية مطلوبة بشكل مباشر في التعليمات البرمجية عالية المستوى التي يتم تشغيلها في سلسلة واجهة المستخدم الرسومية./src/chatClient.h;.cpp
megaPostMessageToGui()
وكيفية بدء "الخدمات" وكيفية إنشاء عميل MEGAchat . يوضح أيضًا كيفية تنفيذ طريقة getAppDir()
، وهو رمز ضعيف تحتاجه مكتبة MEGAchat لإنشاء ملف السجل وبدء التسجيل في أقرب وقت ممكن، قبل إدخال main()
.src/rtcModile/IRtcModule.h
والرؤوس ذات الصلةmegaPostMessageToGui()
، ولكن يمكن أن يكون لها أي اسم، بشرط أن يكون التوقيع extern "C" void(void*)
. هذه الوظيفة هي قلب آلية تمرير الرسائل (التي تسمى Gui Call Marshaller، أو GCM) التي تعتمد عليها MEGAchat . يجب عليك تمرير مؤشر لهذه الوظيفة إلى services_init()
.