Schnellstart: Erstellen Sie eine App, die die Anzahl der GitHub-Sterne mit Azure Functions und dem SignalR-Service mithilfe von Java anzeigt

In diesem Artikel verwenden Sie SignalR Service, Azure Functions und Java, um eine serverlose Anwendung zu erstellen und Nachrichten an Clients zu übertragen.

Hinweis

Der in diesem Artikel verwendete Code ist auf GitHub verfügbar.

Voraussetzungen

  • Ein Code-Editor wie Visual Studio Code

  • Ein Azure-Konto mit einem aktiven Abonnement. Wenn Sie noch nicht über ein Konto verfügen, erstellen Sie ein kostenloses Konto.

  • Azure Functions Core Tools. Dient zum lokalen Ausführen von Azure-Funktions-Apps.

    • Die erforderlichen SignalR Service-Bindungen in Java werden nur in Version 2.4.419 von Azure Function Core Tools (Hostversion 2.0.12332) oder höher unterstützt.
    • Für die Installation von Erweiterungen erfordert Azure Functions Core Tools die Installation des .NET Core SDK. Allerdings sind keine Kenntnisse von .NET erforderlich, um Java Azure Functions-Apps zu erstellen.
  • Java Developer Kit, Version 11

  • Apache Maven, Version 3.0 oder höher

Dieser Schnellstart kann unter MacOS, Windows oder Linux ausgeführt werden.

Erstellen einer Instanz des Azure SignalR-Diensts

In diesem Abschnitt erstellen Sie eine einfache Azure SignalR-Instanz für Ihre App. In den folgenden Schritten wird das Azure-Portal für die Erstellung einer neuen Instanz verwendet. Sie können jedoch auch die Azure CLI verwenden. Weitere Informationen finden Sie unter dem Befehl az signalr create in der Azure SignalR Service-CLI-Referenz.

  1. Melden Sie sich beim Azure-Portal an.
  2. Wählen Sie links oben auf der Seite die Option + Ressource erstellen aus.
  3. Geben Sie auf der Seite Ressource erstellen im Textfeld Dienste und Marketplace durchsuchen den Text signalr ein und wählen Sie dann SignalR Service aus der Liste aus.
  4. Klicken Sie auf der Seite SignalR Service auf Erstellen.
  5. Geben Sie auf der Registerkarte Grundlagen die grundlegenden Informationen für Ihre neue SignalR Service-Instanz ein. Geben Sie die folgenden Werte ein:
Feld Empfohlener Wert BESCHREIBUNG
Abonnement Auswählen Ihres Abonnements Wählen Sie das Abonnement aus, das Sie verwenden möchten, um eine neue SignalR Service-Instanz zu erstellen.
Ressourcengruppe Erstellen einer Ressourcengruppe namens SignalRTestResources Wählen Sie eine Ressourcengruppe für Ihre SignalR-Ressource aus, oder erstellen Sie eine. Es ist hilfreich, für dieses Tutorial eine neue Ressourcengruppe zu erstellen, anstatt eine vorhandene Ressourcengruppe zu verwenden. Löschen Sie die Ressourcengruppe, um nach Abschluss des Tutorials Ressourcen freizugeben.

Durch das Löschen einer Ressourcengruppe werden auch alle Ressourcen dieser Gruppe gelöscht. Diese Aktion kann nicht rückgängig gemacht werden. Bevor Sie eine Ressourcengruppe löschen, stellen Sie sicher, dass sie keine Ressourcen enthält, die Sie behalten möchten.

Weitere Informationen finden Sie unter Verwenden von Ressourcengruppen zum Verwalten von Azure-Ressourcen.
Ressourcenname testsignalr Geben Sie für die SignalR-Ressource einen eindeutigen Ressourcennamen ein. Wenn testsignalr bereits in Ihrer Region belegt ist, fügen Sie Ziffern oder Zeichen hinzu, bis der Name eindeutig ist.

Der Name muss zwischen 1 und 63 Zeichen lang sein und darf nur Zahlen, Buchstaben und den Bindestrich (-) enthalten. Der Name darf weder mit dem Bindestrich beginnen oder enden noch mehrere aufeinanderfolgende Bindestriche enthalten.
Region Wählen Sie Ihre Region aus. Wählen Sie die entsprechende Region für Ihre neue SignalR Service-Instanz aus.

Azure SignalR Service ist derzeit nicht in allen Regionen verfügbar. Weitere Informationen finden Sie unter Verfügbare Produkte nach Region.
Preisstufe Klicken Sie auf Ändern und dann auf Free (nur Dev/Test). Klicken Sie auf Auswählen, um Ihre Tarifauswahl zu bestätigen. Azure SignalR Service bietet drei Tarife: Free, Standard und Premium. Für Tutorials wird der Tarif Free verwendet, sofern in den Voraussetzungen nichts anderes angegeben ist.

Weitere Informationen zu den Funktionsunterschieden zwischen Tarifen und Preisen finden Sie unter Azure SignalR Service – Preise.
Dienstmodus Wählen Sie den entsprechenden Dienstmodus Verwenden Sie Standard, wenn Sie die SignalR-Hublogik in Ihren Web-Apps hosten und den SignalR Service als Proxy verwenden. Verwenden Sie Serverlos, wenn Sie serverlose Technologien wie Azure Functions verwenden, um die SignalR-Hublogik zu hosten.

Der Modus Klassisch ist nur für die Abwärtskompatibilität vorgesehen und wird nicht empfohlen.

Weitere Informationen finden Sie unter Dienstmodi in Azure SignalR Service.

Sie müssen die Einstellungen auf den Registerkarten Netzwerk und Tags für die SignalR-Tutorials nicht ändern.

  1. Klicken Sie unten auf der Registerkarte Grundlagen auf die Schaltfläche Überprüfen und erstellen.
  2. Überprüfen Sie auf der Registerkarte Überprüfen und erstellen die Werte und klicken Sie dann auf Erstellen. Die Bereitstellung dauert ein paar Augenblicke.
  3. Klicken Sie nach Abschluss der Bereitstellung auf die Schaltfläche Zu Ressource wechseln.
  4. Klicken Sie auf der SignalR-Ressourcenseite im Menü auf der linken Seite unter Einstellungen auf Schlüssel.
  5. Kopieren Sie die Verbindungszeichenfolge für den Primärschlüssel. Sie benötigen diese Verbindungszeichenfolge später in diesem Tutorial, um Ihre App zu konfigurieren.

Konfigurieren und Ausführen der Azure Functions-App

Stellen Sie sicher, dass Azure Function Core Tools, Java (Version 11 im Beispiel) und Maven installiert sind.

  1. Initialisieren Sie das Projekt mithilfe von Maven:

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

    Maven fordert Sie zur Eingabe der Werte auf, die erforderlich sind, um die Generierung des Projekts abzuschließen. Geben Sie außerdem die folgenden Werte an:

    Prompt Wert BESCHREIBUNG
    groupId com.signalr Ein Wert, der Ihr Projekt projektübergreifend eindeutig identifiziert. Für den Wert müssen die Paketbenennungsregeln für Java eingehalten werden.
    artifactId java Der Name des Behälters (ohne Versionsnummer).
    version 1.0-SNAPSHOT Wählen Sie den Standardwert aus.
    package com.signalr Das Java-Paket für den generierten Funktionscode. Verwenden Sie den Standardwert.
  2. Wechseln Sie zum Ordner src/main/java/com/signalr, und kopieren Sie den folgenden Code in 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. Einige Abhängigkeiten müssen hinzugefügt werden. Öffnen Sie pom.xml, und fügen Sie die folgenden Abhängigkeiten hinzu, die im Code verwendet werden:

    <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. Die Clientschnittstelle für dieses Beispiels ist eine Webseite. Wir lesen HTML-Inhalte aus content/index.html in der Funktion index und erstellen dann eine neue Datei vom Typ content/index.html im Verzeichnis resources. Ihre Verzeichnisstruktur sollte wie folgt aussehen:

        | - src
        | | - main
        | | | - java
        | | | | - com
        | | | | | - signalr
        | | | | | | - Function.java
        | | | - resources
        | | | | - content
        | | | | | - index.html
        | - pom.xml
        | - host.json
        | - local.settings.json
    
  5. Öffnen Sie index.html, und kopieren Sie den folgenden Inhalt:

    <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. Für Azure Functions ist ein Speicherkonto erforderlich. Sie können den Azure-Speicheremulator installieren und ausführen.

  7. Sie sind jetzt fast fertig. Der letzte Schritt besteht darin, eine Verbindungszeichenfolge des SignalR Service auf die Azure-Function Einstellungen festzulegen.

    1. Suchen Sie die SignalR-Instanz, die Sie zuvor bereitgestellt haben, über das Suchfeld im Azure-Portal. Wählen Sie die Instanz aus, um sie zu öffnen.

      Search for the SignalR Service instance

    2. Wählen Sie Schlüssel aus, um die Verbindungszeichenfolgen für die SignalR-Dienstinstanz anzuzeigen.

      Screenshot that highlights the primary connection string.

    3. Kopieren Sie die primäre Verbindungszeichenfolge, und führen Sie dann den folgenden Befehl aus:

      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. Führen Sie Azure-Function auf lokaler Ebene aus:

    mvn clean package
    mvn azure-functions:run
    

    Navigieren Sie nach dem lokalen Ausführen der Azure-Funktion zu http://localhost:7071/api/index, und die aktuelle Anzahl von Sternen wird angezeigt. Wenn Sie auf GitHub einen Stern vergeben oder entfernen, wird die Anzahl von Sternen alle paar Sekunden aktualisiert.

Bereinigen von Ressourcen

Wenn Sie diese App nicht weiter verwenden möchten, löschen Sie alle von diesem Schnellstart erstellten Ressourcen. Führen Sie dazu folgende Schritte durch, damit keine Gebühren anfallen:

  1. Klicken Sie ganz links im Azure-Portal auf Ressourcengruppen und anschließend auf die erstellte Ressourcengruppe. Alternativ können Sie das Suchfeld verwenden, um nach der Ressourcengruppe anhand ihres Namens zu suchen.

  2. Wählen im Fenster, das geöffnet wird, die Ressourcengruppe aus, und klicken Sie dann auf Ressourcengruppe löschen.

  3. Geben Sie in dem neuen Fenster den Namen der zu löschenden Ressourcengruppe ein, und klicken Sie dann auf Löschen.

Treten Probleme auf? Verwenden Sie den Leitfaden zur Problembehandlung, oder informieren Sie uns.

Nächste Schritte

In dieser Schnellstartanleitung haben Sie eine serverlose Echtzeitanwendung auf einem lokalen Host erstellt und ausgeführt. Als Nächstes erfahren Sie mehr über die bidirektionale Kommunikation zwischen Clients und Azure Function mit dem SignalR Service.