Краткое руководство. Создание бессерверного приложения с помощью Функции Azure и Служба Azure SignalR в Python

Начало работы с Служба Azure SignalR с помощью Функции Azure и Python для создания бессерверного приложения, которое передает сообщения клиентам. Вы запустите функцию в локальной среде, подключаясь к экземпляру Служба Azure SignalR в облаке. Выполнение этого краткого руководства повлечет за собой небольшую стоимость нескольких центов США или меньше в учетной записи Azure.

Примечание.

Вы можете получить код в этой статье из GitHub.

Необходимые компоненты

Это краткое руководство предназначено для macOS, Windows или Linux. Кроме этого, вам понадобится следующее ПО:

Необходимые условия Description
Подписка Azure Если у вас нет подписки Azure, создайте бесплатную учетную запись Azure.
Редактор кода Вам потребуется редактор кода, например Visual Studio Code.
Azure Functions Core Tools Требуется версия 2.7.1505 или более поздней для локального запуска приложений-функций Python.
Python 3.7+ Функции Azure требуется Python 3.7+. См. поддерживаемые версии Python.
Azurite Привязка SignalR требует служба хранилища Azure. При локальной работе функции можно использовать эмулятор локального хранилища.
Azure CLI При необходимости можно использовать Azure CLI для создания экземпляра Служба Azure SignalR.

Создание экземпляра службы Azure SignalR

В этом разделе описано, как создать базовый экземпляр Azure SignalR, используемый для приложения. Следующие действия используют портал Azure для создания нового экземпляра, но также можно использовать Azure CLI. Дополнительные сведения см. в статье az signalr create command in the Служба Azure SignalR CLI Reference.

  1. Войдите на портал Azure.
  2. Щелкните + Создать ресурс в левом верхнем углу страницы.
  3. На странице "Создание ресурса" в текстовом поле служба и Marketplace введите сигнализатор и выберите Служба SignalR из списка.
  4. На странице Служба SignalR нажмите кнопку "Создать".
  5. На вкладке "Основные сведения" введите необходимые сведения для нового экземпляра Служба SignalR. Введите следующие значения:
Поле Рекомендуемое значение Description
Подписка Выберите свою подписку Выберите подписку, которую вы хотите использовать для создания нового экземпляра Служба SignalR.
Группа ресурсов Создайте группу ресурсов с именем SignalRTestResources Выберите или создайте группу ресурсов для ресурса SignalR. Для этого руководства рекомендуется создать новую группу ресурсов вместо использования существующей группы ресурсов. Чтобы освободить ресурсы после завершения работы с руководством, удалите группу ресурсов.

При удалении группы ресурсов также удаляются все ресурсы, принадлежащие группе. Это действие невозможно отменить. Перед удалением группы ресурсов убедитесь, что она не содержит ресурсов, которые вы хотите сохранить.

Дополнительные сведения см. в статье Управление ресурсами Azure через портал.
Имя ресурса testsignalr Введите уникальное имя для ресурса SignalR. Если testsignalr уже взят в регионе, добавьте цифру или символ, пока имя не будет уникальным.

Имя должно быть строкой длиной от 1 до 63 символов и содержать только цифры, буквы и символ -. Имя не может начинаться или заканчиваться символом дефиса, а последовательные символы дефиса недопустимы.
Регион Выберите регион Выберите соответствующий регион для нового экземпляра Служба SignalR.

Служба Azure SignalR сейчас недоступен во всех регионах. Дополнительные сведения см. в разделе Служба Azure SignalR доступности региона
Ценовая категория Выберите "Изменить", а затем выберите "Только для разработки и тестирования". Выберите "Выбрать ", чтобы подтвердить выбор ценовой категории. Служба Azure SignalR имеет три ценовых категории: "Бесплатный", "Стандартный" и "Премиум". Учебники используют уровень "Бесплатный " , если не указано иное в предварительных требованиях.

Дополнительные сведения о различиях функций между уровнями и ценами см. в Служба Azure SignalR ценах
Режим службы Выбор соответствующего режима службы Используйте Значение по умолчанию при размещении логики Концентратора SignalR в веб-приложениях и использовании службы SignalR в качестве прокси-сервера. Используйте бессерверные технологии, такие как Функции Azure для размещения логики концентратора SignalR.

Классический режим предназначен только для обратной совместимости и не рекомендуется использовать.

Дополнительные сведения см. в разделе "Режим службы" в Служба Azure SignalR.

Вам не нужно изменять параметры на вкладках "Сеть и теги " для учебников SignalR.

  1. Нажмите кнопку "Просмотр и создание " в нижней части вкладки "Основные сведения".
  2. На вкладке "Просмотр и создание" просмотрите значения и нажмите кнопку "Создать". Для завершения развертывания потребуется несколько минут.
  3. По завершении развертывания нажмите кнопку "Перейти к ресурсу ".
  4. На странице ресурсов SignalR выберите "Ключи" в меню слева в разделе Параметры.
  5. Скопируйте строку Подключение ion для первичного ключа. Это строка подключения вам потребуется, чтобы настроить приложение позже в этом руководстве.

Создание проекта функции Azure

Создайте локальный проект функции Azure.

  1. В командной строке создайте каталог для проекта.
  2. Перейдите в каталог проекта.
  3. Используйте команду Функции Azure func init для инициализации проекта функции.
# Initialize a function project
func init --worker-runtime python

Создание функций

После инициализации проекта необходимо создать функции. Для этого проекта требуются три функции:

  • index: размещает веб-страницу для клиента.
  • negotiate: позволяет клиенту получить маркер доступа.
  • broadcast: использует триггер времени для периодического трансляции сообщений для всех клиентов.

При выполнении func new команды из корневого каталога проекта Функции Azure 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

Создайте локальный проект функции Azure.

  1. В командной строке создайте каталог для проекта.
  2. Перейдите в каталог проекта.
  3. Используйте команду Функции Azure func init для инициализации проекта функции.
# Initialize a function project
func init --worker-runtime python --model v1

Создание функций

После инициализации проекта необходимо создать функции. Для этого проекта требуются три функции:

  • index: размещает веб-страницу для клиента.
  • negotiate: позволяет клиенту получить маркер доступа.
  • broadcast: использует триггер времени для периодического трансляции сообщений для всех клиентов.

При выполнении func new команды из корневого каталога проекта Функции Azure 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. Измените согласование/_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 строка подключения в параметры приложения-функции

Последним шагом является настройка Служба SignalR строка подключения в параметрах приложения-функции Azure.

  1. В портал Azure перейдите в развернутый ранее экземпляр SignalR.

  2. Выберите ключи для просмотра строк подключения экземпляра службы SignalR.

    Снимок экрана: страница

  3. Скопируйте основной строка подключения и выполните команду:

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

Локальное запуск приложения-функции Azure

Запустите эмулятор хранилища Azurite:

azurite 

Запустите приложение-функцию Azure в локальной среде:

func start

Примечание.

Если вы видите ошибки чтения в хранилище BLOB-объектов, убедитесь, что для параметра AzureWebJobs служба хранилища в файле local.settings.json задано UseDevelopmentStorage=trueзначение.

После локальной работы функции Azure перейдите в раздел http://localhost:7071/api/index. На странице отображается текущее число звезд для репозитория GitHub Azure/azure-signalr. При отображении или отмене репозитория в GitHub вы увидите обновляемое количество каждые несколько секунд.

Очистка ресурсов

Если вы не собираетесь использовать это приложение дальше, удалите все ресурсы, созданные в ходе работы с этим кратким руководством, чтобы не оплачивать их.

  1. На портале Azure выберите Группа ресурсов слева, а затем созданную группу ресурсов. Также можно использовать поле поиска для поиска ресурса по его имени.

  2. В открывшемся окне выберите группу ресурсов и щелкните Удалить группу ресурсов.

  3. В новом окне введите имя группы ресурсов, которую требуется удалить, и щелкните Удалить.

Возникли проблемы? См. руководство по устранению неполадок или сообщите о проблеме нам.

Следующие шаги

В этом кратком руководстве показано, как создать и запустить бессерверное приложение в реальном времени на локальном компьютере. Далее узнайте больше о том, как использовать двунаправленное взаимодействие между клиентами и функцией Azure с Служба SignalR.