التشغيل السريع: إنشاء تطبيق بلا خادم باستخدام Azure Functions وAzure SignalR Service في Python

ابدأ باستخدام Azure SignalR Service باستخدام Azure Functions وPython لإنشاء تطبيق بلا خادم يبث الرسائل للعملاء. ستقوم بتشغيل الدالة في البيئة المحلية، والاتصال بمثيل Azure SignalR Service في السحابة. يتطلب إكمال هذا التشغيل السريع تكلفة صغيرة تبلغ بضعة سنتات أمريكية أو أقل في حساب Azure الخاص بك.

إشعار

يمكنك الحصول على التعليمات البرمجية في هذه المقالة من GitHub.

المتطلبات الأساسية

يمكن تشغيل هذه التشغيل السريع على macOS أو Windows أو Linux. ستحتاج إلى ما يلي:

المتطلب الأساسي ‏‏الوصف
اشتراك Azure إذا لم يكن لديك اشتراك Azure، فبادر بإنشاء حساب Azure مجاني
محرر التعليمات البرمجية ستحتاج إلى محرر تعليمات برمجية مثل Visual Studio Code.
أدوات Azure Functions الأساسية يتطلب الإصدار 2.7.1505 أو أعلى لتشغيل تطبيقات Python Azure Function محليا.
Python 3.7+ تتطلب Azure Functions Python 3.7+. راجع إصدارات Python المدعومة.
Azurite يحتاج ربط SignalR إلى Azure Storage. يمكنك استخدام محاكي تخزين محلي عند تشغيل دالة محليا.
Azure CLI اختياريا، يمكنك استخدام Azure CLI لإنشاء مثيل Azure SignalR Service.

قم بإنشاء مثيل Azure SignalR Service

في هذا القسم، يمكنك إنشاء مثيل Azure SignalR أساسي لاستخدامه لتطبيقك. تستخدم الخطوات التالية مدخل Microsoft Azure لإنشاء مثيل جديد، ولكن يمكنك أيضا استخدام Azure CLI. لمزيد من المعلومات، راجع الأمر az signalr create في مرجع Azure SignalR Service CLI.

  1. قم بتسجيل الدخول إلى بوابة Azure.
  2. في الجانب العلوي الأيسر من الصفحة، اختر+ إنشاء مورد.
  3. في صفحة إنشاء مورد، في مربع النص خدمة البحث والسوق، أدخل signalr ثم حدد SignalR Service من القائمة.
  4. في صفحة SignalR Service ، حدد Create.
  5. في علامة التبويب Basics ، يمكنك إدخال المعلومات الأساسية لمثيل SignalR Service الجديد. أدخل القيم التالية:
الحقل القيم المقترحة ‏‏الوصف
الاشتراك اختر اشتراكك حدد الاشتراك الذي تريد استخدامه لإنشاء مثيل خدمة SignalR جديد.
مجموعة الموارد إنشاء مجموعة موارد باسم SignalRTestResources يوصى باختيار أو إنشاء مجموعة موارد لموردك SignalR. من المفيد إنشاء مجموعة موارد جديدة لهذا البرنامج التعليمي بدلا من استخدام مجموعة موارد موجودة. لتحرير الموارد بعد إكمال البرنامج التعليمي، احذف مجموعة الموارد.

يؤدي حذف مجموعة موارد أيضا إلى حذف كافة الموارد التي تنتمي إلى المجموعة. لا يمكن التراجع عن هذا الإجراء. قبل حذف مجموعة موارد، تأكد من أنها لا تحتوي على موارد تريد الاحتفاظ بها.

للمزيد من المعلومات، يُرجى الرجوع إلى استخدام مجموعات الموارد لإدارة موارد Azure.
اسم المورد testsignalr أدخل اسم مورد مميزًا لاستخدامه في مورد SignalR. إذا تم أخذ testignalr بالفعل في منطقتك، أضف رقما أو حرفا حتى يكون الاسم فريدا.

يجب أن يكون الاسم سلسلة مكونة من 1 إلى 63 حرفًا وتتضمن الأرقام والحروف ورمز الواصلة فقط -. لا يمكن أن يبدأ الاسم أو ينتهي بحرف الواصلة، وأحرف الواصلة المتتالية غير صالحة.
المنطقة اختيار منطقتك حدد المنطقة المناسبة لمثيل SignalR Service الجديد.

خدمة Azure SignalR غير متوفرة حاليا في جميع المناطق. لمزيد من المعلومات، راجع توفر منطقة خدمة Azure SignalR
مستوى الأسعار حدد تغيير ثم اختر مجاني (التطوير/الاختبار فقط). اختر تحديد لتأكيد اختيارك لمستوى التسعير. تحتوي خدمة Azure SignalR على ثلاثة مستويات تسعير: Free وStandard وPremium. تستخدم البرامج التعليمية المستوى المجاني ، ما لم يتم ملاحظة خلاف ذلك في المتطلبات الأساسية.

لمزيد من المعلومات حول اختلافات الوظائف بين المستويات والتسعير، راجع تسعير خدمة Azure SignalR
وضع الخدمة اختر وضع الخدمة المناسب استخدم الافتراضي عند استضافة منطق مركز SignalR في تطبيقات الويب واستخدام خدمة SignalR كوكيل. استخدم Serverless عند استخدام تقنيات بلا خادم مثل Azure Functions لاستضافة منطق مركز SignalR.

الوضع الكلاسيكي هو فقط للتوافق مع الإصدارات السابقة ولا يوصى باستخدامه.

لمزيد من المعلومات، راجع وضع الخدمة في خدمة Azure SignalR.

لا تحتاج إلى تغيير الإعدادات في علامات التبويب الشبكات والعلامات لبرامج SignalR التعليمية.

  1. حدد الزر Review + create أسفل علامة التبويب Basics .
  2. في علامة التبويب Review + create ، راجع القيم ثم حدد Create. يستغرق الأمر بضع لحظات حتى يكتمل النشر.
  3. عند اكتمال النشر، حدد الزر Go to resource .
  4. في صفحة مورد SignalR، حدد Keys من القائمة على اليسار، ضمن الإعدادات.
  5. انسخ سلسلة الاتصال ion للمفتاح الأساسي. تحتاج إلى هذا سلسلة الاتصال لتكوين تطبيقك لاحقا في هذا البرنامج التعليمي.

إنشاء مشروع Azure Function

إنشاء مشروع Azure Function محلي.

  1. من سطر الأوامر، قم بإنشاء دليل لمشروعك.
  2. قم بالتغيير إلى دليل المشروع.
  3. استخدم الأمر Azure Functions func init لتهيئة مشروع الدالة.
# Initialize a function project
func init --worker-runtime python

إنشاء الوظائف

بعد تهيئة المشروع، تحتاج إلى إنشاء دالات. يتطلب هذا المشروع ثلاث وظائف:

  • index: يستضيف صفحة ويب لعميل.
  • negotiate: يسمح للعميل بالحصول على رمز مميز للوصول.
  • broadcast: يستخدم مشغل وقت لبث الرسائل بشكل دوري لجميع العملاء.

عند تشغيل func new الأمر من الدليل الجذر للمشروع، تقوم Azure Functions Core Tools بإلحاق التعليمات البرمجية للوظيفة في function_app.py الملف. ستقوم بتحرير محتوى الإعلان للمعلمات حسب الضرورة عن طريق استبدال التعليمات البرمجية الافتراضية برمز التطبيق.

إنشاء دالة الفهرس

يمكنك استخدام هذه الدالة النموذجية كقالب للدالات الخاصة بك.

افتح الملف function_app.py. سيحتوي هذا الملف على الدالات الخاصة بك. أولا، قم بتعديل الملف لتضمين عبارات الاستيراد الضرورية، وحدد المتغيرات العمومية التي سنستخدمها في الدالات التالية.

import azure.functions as func
import os
import requests
import json 

app = func.FunctionApp()

etag = ''
start_count = 0
  1. إضافة الدالة index عن طريق إضافة التعليمات البرمجية التالية
@app.route(route="index", auth_level=func.AuthLevel.ANONYMOUS)
def index(req: func.HttpRequest) -> func.HttpResponse:
    f = open(os.path.dirname(os.path.realpath(__file__)) + '/content/index.html')
    return func.HttpResponse(f.read(), mimetype='text/html')

تستضيف هذه الدالة صفحة ويب لعميل.

إنشاء دالة التفاوض

إضافة الدالة negotiate عن طريق إضافة التعليمات البرمجية التالية

@app.route(route="negotiate", auth_level=func.AuthLevel.ANONYMOUS, methods=["POST"])
@app.generic_input_binding(arg_name="connectionInfo", type="signalRConnectionInfo", hubName="serverless", connectionStringSetting="AzureSignalRConnectionString")
def negotiate(req: func.HttpRequest, connectionInfo) -> func.HttpResponse:
    return func.HttpResponse(connectionInfo)

تسمح هذه الدالة للعميل بالحصول على رمز مميز للوصول.

إنشاء دالة بث.

إضافة الدالة broadcast عن طريق إضافة التعليمات البرمجية التالية

@app.timer_trigger(schedule="*/1 * * * *", arg_name="myTimer",
              run_on_startup=False,
              use_monitor=False)
@app.generic_output_binding(arg_name="signalRMessages", type="signalR", hubName="serverless", connectionStringSetting="AzureSignalRConnectionString")
def broadcast(myTimer: func.TimerRequest, signalRMessages: func.Out[str]) -> None:
    global etag
    global start_count
    headers = {'User-Agent': 'serverless', 'If-None-Match': etag}
    res = requests.get('https://api.github.com/repos/azure/azure-functions-python-worker', headers=headers)
    if res.headers.get('ETag'):
        etag = res.headers.get('ETag')

    if res.status_code == 200:
        jres = res.json()
        start_count = jres['stargazers_count']

    signalRMessages.set(json.dumps({
        'target': 'newMessage',
        'arguments': [ 'Current star count of https://api.github.com/repos/azure/azure-functions-python-worker is: ' + str(start_count) ]
    }))

تستخدم هذه الدالة مشغل وقت لبث الرسائل بشكل دوري لجميع العملاء.

إنشاء مشروع Azure Function

إنشاء مشروع Azure Function محلي.

  1. من سطر الأوامر، قم بإنشاء دليل لمشروعك.
  2. قم بالتغيير إلى دليل المشروع.
  3. استخدم الأمر Azure Functions func init لتهيئة مشروع الدالة.
# Initialize a function project
func init --worker-runtime python --model v1

إنشاء الوظائف

بعد تهيئة المشروع، تحتاج إلى إنشاء دالات. يتطلب هذا المشروع ثلاث وظائف:

  • index: يستضيف صفحة ويب لعميل.
  • negotiate: يسمح للعميل بالحصول على رمز مميز للوصول.
  • broadcast: يستخدم مشغل وقت لبث الرسائل بشكل دوري لجميع العملاء.

عند تشغيل func new الأمر من الدليل الجذر للمشروع، تقوم Azure Functions Core Tools بإنشاء ملفات مصدر دالة افتراضية وتخزينها في مجلد يسمى بعد الدالة. ستقوم بتحرير الملفات حسب الضرورة لاستبدال التعليمات البرمجية الافتراضية برمز التطبيق.

إنشاء دالة الفهرس

يمكنك استخدام هذه الدالة النموذجية كقالب للدالات الخاصة بك.

  1. قم بتشغيل الأمر التالي لإنشاء الدالة index .
func new -n index -t HttpTrigger
  1. تحرير الفهرس/function.json واستبدال المحتويات برمز json التالي:
{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}
  1. تحرير الفهرس/_init_.py واستبدال المحتويات بالتعليمات البرمجية التالية:
import os

import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:
    f = open(os.path.dirname(os.path.realpath(__file__)) + '/../content/index.html')
    return func.HttpResponse(f.read(), mimetype='text/html')

إنشاء دالة التفاوض

  1. قم بتشغيل الأمر التالي لإنشاء الدالة negotiate .
func new -n negotiate -t HttpTrigger
  1. تحرير التفاوض/function.json واستبدال المحتويات برمز json التالي:
{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    },
    {
      "type": "signalRConnectionInfo",
      "name": "connectionInfo",
      "hubName": "serverless",
      "connectionStringSetting": "AzureSignalRConnectionString",
      "direction": "in"
    }
  ]
}
  1. تحرير negotiate/_init_.py واستبدال المحتويات بالتعليمات البرمجية التالية:
import azure.functions as func


def main(req: func.HttpRequest, connectionInfo) -> func.HttpResponse:
    return func.HttpResponse(connectionInfo)

إنشاء دالة بث.

  1. قم بتشغيل الأمر التالي لإنشاء الدالة broadcast .
func new -n broadcast -t TimerTrigger
# install requests
pip install requests
  1. تحرير البث/function.json واستبدال المحتويات بالتعليمات البرمجية التالية:
{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "name": "myTimer",
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "*/5 * * * * *"
    },
    {
      "type": "signalR",
      "name": "signalRMessages",
      "hubName": "serverless",
      "connectionStringSetting": "AzureSignalRConnectionString",
      "direction": "out"
    }
  ]
}
  1. تحرير البث/_init_.py واستبدال المحتويات بالتعليمات البرمجية التالية:
import requests
import json

import azure.functions as func

etag = ''
start_count = 0

def main(myTimer: func.TimerRequest, signalRMessages: func.Out[str]) -> None:
    global etag
    global start_count
    headers = {'User-Agent': 'serverless', 'If-None-Match': etag}
    res = requests.get('https://api.github.com/repos/azure/azure-signalr', headers=headers)
    if res.headers.get('ETag'):
        etag = res.headers.get('ETag')

    if res.status_code == 200:
        jres = res.json()
        start_count = jres['stargazers_count']

    signalRMessages.set(json.dumps({
        'target': 'newMessage',
        'arguments': [ 'Current star count of https://github.com/Azure/azure-signalr is: ' + str(start_count) ]
    }))

إنشاء ملف index.html

واجهة العميل لهذا التطبيق هي صفحة ويب. index تقرأ الدالة محتوى HTML من ملف content/index.html.

  1. إنشاء مجلد يسمى content في مجلد جذر المشروع.
  2. إنشاء content/index.html الملف.
  3. انسخ المحتوى التالي إلى ملف content/index.html واحفظه:
<html>

<body>
  <h1>Azure SignalR Serverless Sample</h1>
  <div id="messages"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.7/signalr.min.js"></script>
  <script>
    let messages = document.querySelector('#messages');
    const apiBaseUrl = window.location.origin;
    const connection = new signalR.HubConnectionBuilder()
        .withUrl(apiBaseUrl + '/api')
        .configureLogging(signalR.LogLevel.Information)
        .build();
      connection.on('newMessage', (message) => {
        document.getElementById("messages").innerHTML = message;
      });

      connection.start()
        .catch(console.error);
  </script>
</body>

</html>

إضافة سلسلة الاتصال SignalR Service إلى إعدادات تطبيق الوظائف

الخطوة الأخيرة هي تعيين سلسلة الاتصال SignalR Service في إعدادات تطبيق Azure Function.

  1. في مدخل Microsoft Azure، انتقل إلى مثيل SignalR الذي قمت بنشره سابقا.

  2. حدد "Keys" لعرض سلاسل الاتصال لمثيل SignalR Service.

    لقطة شاشة لصفحة مفاتيح خدمة Azure SignalR.

  3. انسخ سلسلة الاتصال الأساسي، ونفذ الأمر:

    func settings add AzureSignalRConnectionString "<signalr-connection-string>"
    

تشغيل تطبيق Azure Function محليا

ابدأ تشغيل محاكي تخزين Azurite:

azurite 

تشغيل تطبيق Azure Function في البيئة المحلية:

func start

إشعار

إذا رأيت أخطاء تظهر أخطاء القراءة على تخزين الكائن الثنائي كبير الحجم، فتأكد من تعيين إعداد "AzureWebJobsStorage" في ملف local.settings.json إلى UseDevelopmentStorage=true.

بعد تشغيل Azure Function محليا، انتقل إلى http://localhost:7071/api/index. تعرض الصفحة عدد النجوم الحالي لمستودع GitHub Azure/azure-signalr. عند نجمة المستودع أو إلغاء تحديده في GitHub، سترى العدد المحدث كل بضع ثوان.

تنظيف الموارد

إذا لم تكن تنوي متابعة استخدام هذا التطبيق، فاحذف كافة الموارد التي تم إنشاؤها بواسطة هذا التشغيل السريع باستخدام الخطوات التالية حتى لا تتحمل أي رسوم:

  1. من القائمة اليسرى في مدخل Azure، حدد مجموعات الموارد ثم حدد مجموعة الموارد التي أنشأتها. بدلاً من ذلك، يمكنك استخدام مربع البحث للبحث عن مجموعة الموارد باسمها.

  2. في النافذة التي ستفتح، حدد مجموعة الموارد، ثم انقر فوق حذف مجموعة الموارد.

  3. في النافذة الجديد، اكتب اسم مجموعة الموارد المراد حذفها، ثم انقر فوق حذف.

هل تواجه مشكلات؟ جرب دليل استكشاف الأخطاء وإصلاحها أو أخبرنا.

الخطوات التالية

في هذا التشغيل السريع، أنشأت تطبيقاً بلا خادم وشغلته في الوقت الحقيقي محلياً. بعد ذلك، تعرف على المزيد حول كيفية استخدام الاتصال ثنائي الاتجاه بين العملاء وAzure Function مع SignalR Service.