Краткое руководство. Создание приложения для отображения количества звездочек на странице GitHub с помощью Службы Azure SignalR, Функций Azure и Java

В этой статье вы будете использовать Служба Azure SignalR, Функции Azure и Java для создания бессерверного приложения для трансляции сообщений клиентам.

Примечание.

Код, приведенный в этой статье, доступен на сайте GitHub.

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

  • Редактор кода, например Visual Studio Code.

  • Учетная запись Azure с активной подпиской. Если у вас еще нет учетной записи, создайте учетную запись бесплатно.

  • Azure Functions Core Tools. Используется для локального запуска приложений-функций Azure.

    • Требуемые привязки службы SignalR в Java поддерживаются только в Azure Functions Core Tools версии 2.4.419 (версия хоста 2.0.12332) или выше.
    • Чтобы установить расширения, для Azure Functions Core Tools необходимо, чтобы был установлен пакет SDK для .NET Core. Однако для создания приложений-функций Java Azure не требуется никаких знаний о .NET.
  • Java Developer Kit (JDK) версии 11.

  • Apache Maven 3.0 или более поздней версии.

Это краткое руководство предназначено для macOS, Windows или Linux.

Создание экземпляра службы 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 Function Core, Java (версия 11 в примере) и Maven.

  1. Инициализировать проект с помощью Maven:

    mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=11
    

    Maven запрашивает значения, необходимые для завершения создания проекта. Укажите следующие значения:

    Prompt значение Описание
    groupId com.signalr Это значение уникально идентифицирует проект среди всех остальных. Оно должно соответствовать правилам именования пакетов для Java.
    artifactId java Это значение содержит имя JAR-файла, без номера версии.
    version 1.0-SNAPSHOT Выберите значение по умолчанию.
    package com.signalr Это значение определяет пакет Java для создаваемого кода функции. Используйте значение по умолчанию.
  2. Перейдите в папку src/main/java/com/signalr и скопируйте следующий код в Function.java:

    package com.signalr;
    
    import com.google.gson.Gson;
    import com.microsoft.azure.functions.ExecutionContext;
    import com.microsoft.azure.functions.HttpMethod;
    import com.microsoft.azure.functions.HttpRequestMessage;
    import com.microsoft.azure.functions.HttpResponseMessage;
    import com.microsoft.azure.functions.HttpStatus;
    import com.microsoft.azure.functions.annotation.AuthorizationLevel;
    import com.microsoft.azure.functions.annotation.FunctionName;
    import com.microsoft.azure.functions.annotation.HttpTrigger;
    import com.microsoft.azure.functions.annotation.TimerTrigger;
    import com.microsoft.azure.functions.signalr.*;
    import com.microsoft.azure.functions.signalr.annotation.*;
    
    import org.apache.commons.io.IOUtils;
    
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URI;
    import java.net.http.HttpClient;
    import java.net.http.HttpRequest;
    import java.net.http.HttpResponse;
    import java.net.http.HttpResponse.BodyHandlers;
    import java.nio.charset.StandardCharsets;
    import java.util.Optional;
    
    public class Function {
        private static String Etag = "";
        private static String StarCount;
    
        @FunctionName("index")
        public HttpResponseMessage run(
                @HttpTrigger(
                    name = "req",
                    methods = {HttpMethod.GET},
                    authLevel = AuthorizationLevel.ANONYMOUS)HttpRequestMessage<Optional<String>> request,
                final ExecutionContext context) throws IOException {
    
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream("content/index.html");
            String text = IOUtils.toString(inputStream, StandardCharsets.UTF_8.name());
            return request.createResponseBuilder(HttpStatus.OK).header("Content-Type", "text/html").body(text).build();
        }
    
        @FunctionName("negotiate")
        public SignalRConnectionInfo negotiate(
                @HttpTrigger(
                    name = "req",
                    methods = { HttpMethod.POST },
                    authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> req,
                @SignalRConnectionInfoInput(
                    name = "connectionInfo",
                    hubName = "serverless") SignalRConnectionInfo connectionInfo) {
    
            return connectionInfo;
        }
    
        @FunctionName("broadcast")
        @SignalROutput(name = "$return", hubName = "serverless")
        public SignalRMessage broadcast(
            @TimerTrigger(name = "timeTrigger", schedule = "*/5 * * * * *") String timerInfo) throws IOException, InterruptedException {
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest req = HttpRequest.newBuilder().uri(URI.create("https://api.github.com/repos/azure/azure-signalr")).header("User-Agent", "serverless").header("If-None-Match", Etag).build();
            HttpResponse<String> res = client.send(req, BodyHandlers.ofString());
            if (res.headers().firstValue("Etag").isPresent())
            {
                Etag = res.headers().firstValue("Etag").get();
            }
            if (res.statusCode() == 200)
            {
                Gson gson = new Gson();
                GitResult result = gson.fromJson(res.body(), GitResult.class);
                StarCount = result.stargazers_count;
            }
    
            return new SignalRMessage("newMessage", "Current start count of https://github.com/Azure/azure-signalr is:".concat(StarCount));
        }
    
        class GitResult {
            public String stargazers_count;
        }
    }
    
  3. Требуется добавить некоторые зависимости. Откройте pom.xml и добавьте следующие зависимости, используемые в коде:

    <dependency>
        <groupId>com.microsoft.azure.functions</groupId>
        <artifactId>azure-functions-java-library-signalr</artifactId>
        <version>1.0.0</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.7</version>
    </dependency>
    
  4. Клиентский интерфейс для этого примера — это веб-страница. Мы считываем HTML-содержимое из content/index.html в index функции, а затем создадим новый файл content/index.html в каталогеresources. Дерево каталогов должно выглядеть следующим образом:

        | - src
        | | - main
        | | | - java
        | | | | - com
        | | | | | - signalr
        | | | | | | - Function.java
        | | | - resources
        | | | | - content
        | | | | | - index.html
        | - pom.xml
        | - host.json
        | - local.settings.json
    
  5. Откройте 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>
    
  6. Функции Azure требуется, чтобы учетная запись хранения работала. Вы можете установить и запустить эмулятор служба хранилища Azure.

  7. Вы почти сделали сейчас. Нам осталось определить строку подключения Службы SignalR в параметрах экземпляра Функций Azure.

    1. Выполните поиск экземпляра Azure SignalR, развернутого ранее, с помощью поля поиска в портал Azure. Выберите экземпляр, чтобы открыть его.

      Search for the SignalR Service instance

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

      Screenshot that highlights the primary connection string.

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

      func settings add AzureSignalRConnectionString "<signalr-connection-string>"
      # Also we need to set AzureWebJobsStorage as Azure Function's requirement
      func settings add AzureWebJobsStorage "UseDevelopmentStorage=true"
      
  8. Запустите экземпляр Функций Azure на локальном компьютере.

    mvn clean package
    mvn azure-functions:run
    

    После локальной работы функции Azure перейдите http://localhost:7071/api/index и увидите текущее число звезд. Если вы видите или "unstar" в GitHub, вы получите количество звезд, обновляющихся каждые несколько секунд.

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

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

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

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

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

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

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

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