هذا تطبيق توضيحي وعينة تم تصميمه ليكون نظامًا بسيطًا للدردشة عبر الويب متعدد المستخدمين.
فهو يوفر محادثات جماعية مستمرة، ومحادثات خاصة من مستخدم إلى مستخدم، وقائمة مستخدمين، واكتشاف الخمول (بعيدًا عن لوحة المفاتيح) والعديد من الميزات الأخرى.
إنه مبني على العديد من تقنيات Azure، بما في ذلك: Web PubSub، وتطبيقات الويب الثابتة ، وتخزين الجدول
?? ملحوظة. تم إنشاء هذا كمشروع شخصي، تم إنشاؤه للمساعدة في التعلم أثناء بناء شيء مثير للاهتمام. يأتي الكود مع جميع التحذيرات التي قد تتوقعها من مثل هذا المشروع.
الأهداف:
حالات الاستخدام والميزات الرئيسية:
هذه هي واجهة الويب الرئيسية التي يستخدمها المستخدمون النهائيون عبر المتصفح.
تم العثور على مصدر ذلك في العميل/ ويتكون من تطبيق ES6 JS ثابت ومستقل، ولا يلزم وجود تجميع أو Node.js. تمت كتابته باستخدام Vue.js كإطار داعم، وBulma كإطار عمل CSS.
بعض الملاحظات:
client/js/app.js
كيفية إنشاء تطبيق Vue.js بمكونات فرعية باستخدام هذا الأسلوب. غالبية منطق العميل موجود هنا.client/js/components/chat.js
هو مكون Vue.js يستخدم لاستضافة كل علامة تبويب دردشة في التطبيق.auth/
الخاصة التي توفرها Static Web Apps لتسجيل دخول المستخدمين وجلب تفاصيل المستخدم الخاصة بهم، مثل معرف المستخدم.هذه هي الواجهة الخلفية، التي تتعامل مع أحداث websocket من وإلى Azure Web PubSub، وتوفر REST API لبعض العمليات.
تم العثور على مصدر ذلك في api/ ويتكون من تطبيق Node.js Azure Function. إنه يتصل بـ Azure Table Storage للحفاظ على الدردشة الجماعية وبيانات المستخدم (تم اختيار Table Storage لأنه بسيط ورخيص). لا تتم استضافته في تطبيق Azure Function المستقل، ولكن يتم نشره بدلاً من ذلك في تطبيق الويب الثابت كجزء من دعم واجهة برمجة التطبيقات (API) بدون خادم.
هناك أربع وظائف HTTP يتم تقديمها جميعًا من المسار الافتراضي /api/
eventHandler
- جهاز استقبال Webhook للأحداث "المنبعية" المرسلة من خدمة Azure Web PubSub، يحتوي على غالبية منطق التطبيق. لا يتم استدعاؤه مباشرة من قبل العميل، فقط Azure WebPub Sub.getToken
- يتم استدعاؤه بواسطة العميل للحصول على رمز وصول وعنوان URL للاتصال عبر WebSockets بخدمة Azure Web PubSub. يجب استدعاؤه باستخدام معرف المستخدم في استعلام عنوان URL، على سبيل المثال GET /api/getToken?userId={user}
getUsers
- يعرض قائمة بالمستخدمين الذين سجلوا دخولهم، لاحظ أن مسار هذه الوظيفة هو /api/users
getChats
- يعرض قائمة بالمحادثات الجماعية النشطة، لاحظ أن مسار هذه الوظيفة هو /api/chats
يتم التعامل مع الحالة باستخدام state.js
وهي وحدة ES6 التي تصدر وظائف تدعم الحالة CRUD للمستخدمين والمحادثات. تنفذ هذه الوحدة كل التفاعلات مع جداول Azure، وتوفر واجهة شفافة نسبيًا، بحيث يمكن تبديل واجهة تخزين خلفية مختلفة.
يوجد تدفق للرسائل في اتجاهين بين العملاء والخادم عبر Azure Web PubSub ومعالجات الأحداث
يتم استخدام البروتوكول الفرعي json.webpubsub.azure.v1 بدلاً من WebSockets الأساسي، وهذا يوفر عددًا من الميزات: يمكن إضافة المستخدمين إلى المجموعات، ويمكن للعملاء إرسال أحداث مخصصة (باستخدام type: event
)، وكذلك إرسال رسائل مباشرة إلى عملاء آخرين دون المرور عبر الخادم (باستخدام type: sendToGroup
)
ملحوظات:
يتم إرسال الأحداث والدردشة باستخدام البروتوكول الفرعي json.webpubsub.azure.v1
تستخدم رسائل الدردشة المرسلة من العميل sendToGroup
وحمولة JSON مخصصة مع message
ثلاثة حقول، fromUserId
و fromUserName
، يتم ترحيل هذه الرسائل من العميل إلى العميل بواسطة Azure Web PubSub، ولا يتم إخطار الخادم بها مطلقًا:
{
type : 's endToGroup ',
group : < chatId > ,
dataType : 'j son ',
data : {
message : < message text > ,
fromUserId : < userId > ,
fromUserName : < userName > ,
},
}
يتم إرسال الأحداث الموجهة إلى خادم الواجهة الخلفية كرسائل WebSocket من العميل عبر نفس البروتوكول الفرعي مع نوع event
ونوع فرعي محدد للتطبيق، على سبيل المثال
{
type : 'e vent ',
event : 'j oinChat ',
dataType : 't ext ',
data : < chatId > ,
}
أنواع الأحداث هي:
تحتوي وظيفة eventHandler
الخاصة بواجهة برمجة التطبيقات الخلفية على حالات لكل حدث من أحداث المستخدم هذه، بالإضافة إلى معالجات لأحداث نظام الاتصال وقطع الاتصال.
تحتوي الرسائل المرسلة من الخادم على حمولة مخصصة لتطبيق Chatr كما يلي:
{
chatEvent : < eventType > ,
data : < JSON object type dependant >
}
حيث يكون eventType
واحدًا مما يلي:
يتعامل رمز العميل في client/js/app.js
مع هذه الرسائل فور استلامها من قبل العميل، ويتفاعل وفقًا لذلك.
كانت خطة هذا المشروع هي استخدام Azure Web PubSub و Azure Static Web Apps ، واستضافة مكون جانب الخادم كمجموعة من الوظائف بدون خادم في دعم Static Web Apps API (والتي هي في الواقع وظائف Azure تحت الغطاء). تم اختيار Azure Static Web Apps لأنها تتمتع بدعم مذهل لتسجيل دخول ومصادقة المستخدم بدون تعليمات برمجية وبدون تكوين، وهو ما أردت الاستفادة منه.
بعض التعليقات على هذا النهج:
webPubSubConnection
. لإرسال الرسائل مرة أخرى إلى Web PubSub، يمكن ببساطة استخدام SDK للخادم ضمن رمز الوظيفة بدلاً من استخدام ربط إخراج webPubSub
. تتكون الحالة في جداول Azure من جدولين (مجموعات) تسمى chats
users
نظرًا لأن كل دردشة تحتوي على كائنات متداخلة داخل حقل الأعضاء، يتم تخزين كل دردشة كسلسلة JSON في حقل يسمى data
. لا يتم استخدام PartitionKey وترميزه ضمن سلسلة "chatr". مفتاح الصف وحقل المعرف داخل كائن البيانات متماثلان.
مثال لكيان بيانات الدردشة
{
"id" : " eab4b030-1a3d-499a-bd89-191578395910 " ,
"name" : " This is a group chat " ,
"members" : {
"0987654321" : {
"userId" : " 0987654321 " ,
"userName" : " Another Guy "
},
"1234567890" : {
"userId" : " 1234567890 " ,
"userName" : " Ben "
}
},
"owner" : " 1234567890 "
}
يتم تخزين المستخدمين ككيانات تحتوي على الحقول (الأعمدة) الموضحة أدناه. نظرًا لعدم وجود حقول متداخلة، ليست هناك حاجة للتشفير كسلسلة JSON. مرة أخرى، لا يتم استخدام PartitionKey وترميزه ضمن سلسلة "chatr".
userId
من نقطة نهاية مصادقة تطبيقات الويب الثابتةtwitter
أو aad
أو github
انظر ملف التعريف
$ make
help This help message
lint ? Lint & format, will not fix but sets exit code on error
lint-fix Lint & format, will try to fix errors and modify code
run ? Run server locally using Static Web Apps CLI
clean ? Clean up project
deploy Deploy everything to Azure using Bicep
tunnel ? Start loophole tunnel to expose localhost
يعد النشر معقدًا بعض الشيء نظرًا لعدد المكونات والتكوين بينها. يجب deploy
هدف makefile المستهدف كل شيء لك في خطوة واحدة باستخدام قوالب Bicep الموجودة في مجلد النشر/
راجع الملف التمهيدي في مجلد النشر للحصول على التفاصيل والتعليمات
هذا ممكن ولكنه يتطلب القليل من الجهد حيث تحتاج خدمة Azure Web PubSub إلى أن تكون قادرة على الاتصال بنقطة نهاية HTTP على جهاز الموقع الخاص بك، لذلك تم استخدام النفق.
عند التشغيل محليًا، يتم استخدام واجهة سطر أوامر Static Web Apps وهذا يوفر لنا نقطة نهاية وهمية لمصادقة المستخدم.
ملخص الخطوات هو:
api/local.settings.sample.json
إلى api/local.settings.json
وقم بتحرير قيم الإعدادات المطلوبة.loophole http 7071 --hostname chatr
https://{{hostname-of-tunnel-service}}/api/eventHandler
make run
http://localhost:4280/index.html