البرنامج التعليمي: إنشاء تطبيق دردشة في الوقت الحقيقي بلا خادم باستخدام Azure Functions وخدمة Azure Web PubSub
تساعدك خدمة Azure Web PubSub في إنشاء تطبيقات ويب للمراسلة في الوقت الفعلي باستخدام WebSockets ونمط النشر والاشتراك بسهولة. Azure Functions هو نظام أساسي بلا خادم يتيح لك تشغيل التعليمات البرمجية دون إدارة أي بنية أساسية. في هذا البرنامج التعليمي، ستتعلم كيفية استخدام خدمة Azure Web PubSub وAzure Functions لإنشاء تطبيق بلا خادم مع مراسلة في الوقت الفعلي ونمط اشتراك للنشر.
في هذا البرنامج التعليمي، تتعلم كيفية:
- إنشاء تطبيق دردشة في الوقت الفعلي بلا خادم
- العمل مع روابط المشغل لدالة Web PubSub وارتباطات الإخراج
- توزيع الدالة إلى تطبيق Azure Function
- تكوين مصادقة Azure
- تكوين Web PubSub Event Handler لتوجيه الأحداث والرسائل إلى التطبيق
هام
تظهر سلسلة الاتصال الأولية في هذه المقالة لأغراض العرض التوضيحي فقط.
سلسلة اتصال تتضمن معلومات التخويل المطلوبة لتطبيقك للوصول إلى خدمة Azure Web PubSub. مفتاح الوصول داخل سلسلة الاتصال يشبه كلمة مرور الجذر للخدمة الخاصة بك. في بيئات الإنتاج، قم دائما بحماية مفاتيح الوصول الخاصة بك. استخدم Azure Key Vault لإدارة مفاتيحك وتدويرها بأمان وتأمين اتصالك ب WebPubSubServiceClient
.
تجنب توزيع مفاتيح الوصول إلى مستخدمين آخرين، أو ترميزها ترميزًا ثابتًا، أو حفظها في أي مكان في نص عادي يمكن للآخرين الوصول إليه. قم بتدوير المفاتيح الخاصة بك إذا كنت تعتقد أنها قد تعرضت للخطر.
المتطلبات الأساسية
محرر التعليمات البرمجية، مثل Visual Studio Code
Node.js، الإصدار 18.x أو أعلى.
إشعار
لمزيد من المعلومات حول الإصدارات المدعومة من Node.js، راجع وثائق إصدارات وقت تشغيل Azure Functions.
Azure Functions Core Tools (الإصدار 4 أو أعلى مفضل) لتشغيل تطبيقات Azure Function محليا ونشرها في Azure.
Azure CLI لإدارة موارد Azure.
إذا لم يكن لديك اشتراك في Azure، فأنشئ حساب Azure مجاني قبل أن تبدأ.
تسجيل الدخول إلى Azure
سجل الدخول إلى مدخل Microsoft Azure على https://portal.azure.com/ باستخدام بيانات حساب Azure.
إنشاء مثيل خدمة Azure Web PubSub
سيقوم التطبيق بالاتصال بمثيل خدمة Web PubSub في Azure.
حدد الزر جديد «New» الموجود في الزاوية العلوية اليسرى من مدخل Microsoft Azure. في الشاشة «New»، اكتب «Web PubSub» في مربع البحث واضغط على إدخال. (يمكنك أيضًا البحث في Azure Web PubSub من الفئة
Web
.)حدد «Web PubSub» من نتائج البحث، ثم حدد «Create».
أدخل الإعدادات التالية.
الإعدادات القيمة المقترحة الوصف اسم المورد اسم فريد عالميًا الاسم الفريد العام الذي يعرّف مثيل خدمة Web PubSub الجديد. الأحرف الصالحة هي a-z
وA-Z
0-9
و و.-
الاشتراك اشتراكك اشتراك Azure الذي يتم بموجبه إنشاء مثيل خدمة Web PubSub الجديد هذا. مجموعة الموارد myResourceGroup اسم مجموعة الموارد الجديدة التي يتم فيها إنشاء مثيل خدمة Web PubSub. Location غرب الولايات المتحدة اختر منطقة قريبة منك. مستوى الأسعار مجاني يمكنك أولًا تجربة خدمة Azure Web PubSub مجانًا. تعرف على مزيد من التفاصيل حول مستويات تسعير خدمة Azure Web PubSub عدد الوحدات - يحدد عدد الوحدات عدد الاتصالات التي يمكن لمثيل خدمة PubSub على الويب قبولها. تدعم كل وحدة 1000 اتصال متزامن على الأكثر. لا يمكن تكوينه إلا في المستوى القياسي. حدد «Create» لبدء نشر مثيل خدمة Web PubSub.
إنشاء الوظائف
تأكد من تثبيت Azure Functions Core Tools. ثم قم بإنشاء دليل فارغ للمشروع. قم بتشغيل الأمر ضمن دليل العمل هذا.
func init --worker-runtime javascript --model V4
تثبيت
Microsoft.Azure.WebJobs.Extensions.WebPubSub
.قم بتأكيد وتحديث
host.json
extensionBundle إلى الإصدار 4.* أو أحدث للحصول على دعم Web PubSub.{ "extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", "version": "[4.*, 5.0.0)" } }
قم بإنشاء دالة
index
لقراءة واستضافة صفحة ويب ثابتة للعملاء.func new -n index -t HttpTrigger
- قم بتحديث
src/functions/index.js
وانسخ التعليمات البرمجية التالية.const { app } = require('@azure/functions'); const { readFile } = require('fs/promises'); app.http('index', { methods: ['GET', 'POST'], authLevel: 'anonymous', handler: async (context) => { const content = await readFile('index.html', 'utf8', (err, data) => { if (err) { context.err(err) return } }); return { status: 200, headers: { 'Content-Type': 'text/html' }, body: content, }; } });
- قم بتحديث
أنشئ الدالة
negotiate
لمساعدة العملاء في الحصول على عنوان url لاتصال الخدمة مع رمز الوصول المميز.func new -n negotiate -t HttpTrigger
إشعار
في هذا النموذج، نستخدم عنوان
x-ms-client-principal-name
هوية مستخدم معرف Microsoft Entra لاستردادuserId
. وهذا لن ينجح في دالة محلية. يمكنك جعله فارغًا أو التغيير إلى طرق أخرى للحصول على أو إنشاءuserId
عند اللعب باللغة المحلية. على سبيل المثال، اسمح للعميل بكتابة اسم مستخدم وتمريره في استعلام مثل دالة?user={$username}
عند استدعاء الدالةnegotiate
للحصول على عنوان URL لاتصال الخدمة. في الدالةnegotiate
، اضبطuserId
بقيمة{query.user}
.- قم بتحديث
src/functions/negotiate
وانسخ التعليمات البرمجية التالية.const { app, input } = require('@azure/functions'); const connection = input.generic({ type: 'webPubSubConnection', name: 'connection', userId: '{headers.x-ms-client-principal-name}', hub: 'simplechat' }); app.http('negotiate', { methods: ['GET', 'POST'], authLevel: 'anonymous', extraInputs: [connection], handler: async (request, context) => { return { body: JSON.stringify(context.extraInputs.get('connection')) }; }, });
- قم بتحديث
قم بإنشاء دالة
message
لبث رسائل العميل من خلال الخدمة.func new -n message -t HttpTrigger
- قم بتحديث
src/functions/message.js
وانسخ التعليمات البرمجية التالية.const { app, output, trigger } = require('@azure/functions'); const wpsMsg = output.generic({ type: 'webPubSub', name: 'actions', hub: 'simplechat', }); const wpsTrigger = trigger.generic({ type: 'webPubSubTrigger', name: 'request', hub: 'simplechat', eventName: 'message', eventType: 'user' }); app.generic('message', { trigger: wpsTrigger, extraOutputs: [wpsMsg], handler: async (request, context) => { context.extraOutputs.set(wpsMsg, [{ "actionName": "sendToAll", "data": `[${context.triggerMetadata.connectionContext.userId}] ${request.data}`, "dataType": request.dataType }]); return { data: "[SYSTEM] ack.", dataType: "text", }; } });
- قم بتحديث
أضف صفحة
index.html
العميل الفردية في المجلد الجذر للمشروع وانسخ المحتوى.<html> <body> <h1>Azure Web PubSub Serverless Chat App</h1> <div id="login"></div> <p></p> <input id="message" placeholder="Type to chat..." /> <div id="messages"></div> <script> (async function () { let authenticated = window.location.href.includes( "?authenticated=true" ); if (!authenticated) { // auth let login = document.querySelector("#login"); let link = document.createElement("a"); link.href = `${window.location.origin}/.auth/login/aad?post_login_redirect_url=/api/index?authenticated=true`; link.text = "login"; login.appendChild(link); } else { // negotiate let messages = document.querySelector("#messages"); let res = await fetch(`${window.location.origin}/api/negotiate`, { credentials: "include", }); let url = await res.json(); // connect let ws = new WebSocket(url.url); ws.onopen = () => console.log("connected"); ws.onmessage = (event) => { let m = document.createElement("p"); m.innerText = event.data; messages.appendChild(m); }; let message = document.querySelector("#message"); message.addEventListener("keypress", (e) => { if (e.charCode !== 13) return; ws.send(message.value); message.value = ""; }); } })(); </script> </body> </html>
إنشاء تطبيق وظائف Azure ونشره
قبل أن تتمكن من نشر رمز دالتك على Azure، تحتاج إلى إنشاء ثلاثة موارد:
- مجموعة الموارد عبارة عن حاوية منطقية للموارد.
- حساب تخزين، وهو يستخدم للاحتفاظ بالحالة والمعلومات الأخرى بشأن الدوال لديك.
- تطبيق الوظيفة، الذي يوفر البيئة لتنفيذ التعليمة البرمجية للوظيفة. يتيح تطبيق الدالة التعيين إلى مشروع الدالة المحلي وتجميع الدوال كوحدة منطقية لتيسير إدارة الموارد وتوزيعها ومشاركتها.
استخدم الأوامر التالية لإنشاء هذه العناصر.
إذا لم تكن قد فعلت ذلك بالفعل، سجل الدخول إلى Azure:
az login
إنشاء مجموعة موارد أو يمكنك التخطي عن طريق إعادة استخدام إحدى خدمات Azure Web PubSub:
az group create -n WebPubSubFunction -l <REGION>
إنشاء حساب تخزين للأغراض العامة في مجموعة الموارد والمنطقة الخاصة بك:
az storage account create -n <STORAGE_NAME> -l <REGION> -g WebPubSubFunction
أنشئ تطبيق الدالة في Azure:
az functionapp create --resource-group WebPubSubFunction --consumption-plan-location <REGION> --runtime node --runtime-version 18 --functions-version 4 --name <FUNCIONAPP_NAME> --storage-account <STORAGE_NAME>
إشعار
تحقق من وثائق إصدارات وقت تشغيل Azure Functions لتعيين
--runtime-version
المعلمة إلى القيمة المدعومة.انشر مشروع الدالة في Azure:
بعد إنشاء تطبيق الوظائف الخاص بك بنجاح في Azure، أنت الآن جاهز لنشر مشروع الوظائف المحلية باستخدام الأمر func azure functionapp publish .
func azure functionapp publish <FUNCIONAPP_NAME>
تكوين
WebPubSubConnectionString
لتطبيق الدالة الجديدة:تظهر سلسلة الاتصال الأولية في هذه المقالة لأغراض العرض التوضيحي فقط. في بيئات الإنتاج، قم دائما بحماية مفاتيح الوصول الخاصة بك. استخدم Azure Key Vault لإدارة مفاتيحك وتدويرها بأمان وتأمين اتصالك ب
WebPubSubServiceClient
.أولاً، ابحث عن مورد Web PubSub من مدخل Microsoft Azure وانسخ سلسلة الاتصال ضمن مفاتيح. ثم انتقل إلى Function App settings في مدخل Microsoft Azure ->Settings ->Environment variables. وإضافة عنصر جديد ضمن إعدادات التطبيق، مع الاسم يساوي
WebPubSubConnectionString
والقيمة هي مورد Web PubSub سلسلة الاتصال.
تكوين خدمة Web PubSub Event Handler
في هذه العينة، نستخدم WebPubSubTrigger
للاستماع إلى طلبات المصدر للخدمة. لذلك يحتاج Web PubSub إلى معرفة معلومات نقطة النهاية الخاصة بالدالة من أجل إرسال طلبات العميل المستهدفة. ويتطلب تطبيق Azure Function مفتاح نظام للأمان فيما يتعلق بأساليب webhook الخاصة بالملحق. في الخطوة السابقة بعد نشر تطبيق الدالة بوظائف message
، يمكننا الحصول على مفتاح النظام.
انتقل إلى مدخل Microsoft Azure -> ابحث عن مورد Function App ->مفاتيح التطبيق ->مفاتيح النظام ->webpubsub_extension
. انسخ القيمة كـ <APP_KEY>
.
قم بتعيين Event Handler
في خدمة Azure Web PubSub. انتقل إلى مدخل Microsoft Azure -> ابحث عن مورد Web PubSub ->Settings. إضافة تعيين إعدادات مركز جديد إلى الدالة الواحدة المستخدمة. استبدل <FUNCTIONAPP_NAME>
و<APP_KEY>
لك.
- اسم المركز:
simplechat
- قالب URL: https://< FUNCTIONAPP_NAME.azurewebsites.net/runtime/webhooks/webpubsub?code>=<APP_KEY>
- نمط حدث المستخدم: *
- أحداث النظام: - (لا حاجة للتكوين في هذا النموذج)
تكوين لتمكين مصادقة العميل
انتقل إلى مدخل Microsoft Azure -> ابحث عن مورد Function App ->Authentication. انقر فوق Add identity provider
. قم بتعيين إعدادات مصادقة App Service إلى السماح بالوصول غير المصادق عليه، بحيث يمكن زيارة صفحة فهرس العميل من قبل مستخدمين مجهولين قبل إعادة التوجيه للمصادقة. ثم احفظ.
هنا نختار Microsoft
كموفر تعريف، والذي يستخدم x-ms-client-principal-name
كما هو الحال userId
في الدالة negotiate
. بالإضافة إلى ذلك، يمكنك تكوين موفري الهوية الآخرين باتباع الارتباطات، ولا تنس تحديث القيمة في negotiate
الدالة userId
وفقا لذلك.
جرب التطبيق
يمكنك الآن اختبار صفحتك من تطبيق وظيفتك: https://<FUNCTIONAPP_NAME>.azurewebsites.net/api/index
. راجع اللقطة.
- انقر فوق
login
to auth yourself. - اكتب رسالة في مربع الإدخال للدردشة.
في دالة الرسالة، نقوم ببث رسالة المتصل إلى جميع العملاء ونعيد المتصل بالرسالة [SYSTEM] ack
. لذلك يمكننا أن نعرف في عينة لقطة الدردشة، أول أربع رسائل من العميل الحالي وآخر رسالتين من عميل آخر.
تنظيف الموارد
إذا كنت لن تستمر في استخدام هذا التطبيق، فاحذف جميع الموارد التي تم إنشاؤها بواسطة هذا المستند من خلال الخطوات التالية حتى لا تتحمل أي رسوم:
من القائمة اليسرى في مدخل Azure، حدد مجموعات الموارد ثم حدد مجموعة الموارد التي أنشأتها. يمكنك استخدام مربع البحث للعثور على resourceGroup باسمها بدلاً من ذلك.
في النافذة التي تفتح، حدد resourceGroup، ثم حدد Delete resource group.
في النافذة الجديدة، اكتب اسم resourceGroup المراد حذفها، ثم حدد Delete.
الخطوات التالية
في هذا التشغيل السريع، تعلمت كيفية تشغيل تطبيق دردشة بلا خادم. الآن، يمكنك البدء في إنشاء تطبيقك.