Übung: Verwenden eines Speicherkontos zum Hosten einer statischen Website

Abgeschlossen

Nachdem die API nun in der Cloud bereitgestellt wurde, müssen Sie den Clientcode aktualisieren und bereitstellen, um die SignalR-Nachrichten zu unterstützen, die für Azure Functions verfügbar sind.

Aktualisieren Sie die Clientanwendung

  1. Öffnen Sie in Visual Studio Code ./start/client/src/index.js, und ersetzen Sie den gesamten Code, um SignalR-Meldungen zu überwachen. Der Code ruft die ursprüngliche Bestandsliste mit einer HTTP-Anforderung ab und lauscht dann auf Updates aus der SignalR-Verbindung. Wenn ein Bestand aktualisiert wird, aktualisiert der Client den Bestandskurs auf der Benutzeroberfläche.

    import './style.css';
    import { BACKEND_URL } from './env';
    
    const app = new Vue({
        el: '#app',
        data() {
            return {
                stocks: []
            }
        },
        methods: {
            async getStocks() {
                try {
    
                    const url = `${BACKEND_URL}/api/getStocks`;
                    console.log('Fetching stocks from ', url);
    
                    const response = await fetch(url);
                    if (!response.ok) {
                        throw new Error(`HTTP error! status: ${response.status} - ${response.statusText}`);
                    }
                    app.stocks = await response.json();
                } catch (ex) {
                    console.error(ex);
                }
            }
        },
        created() {
            this.getStocks();
        }
    });
    
    const connect = () => {
    
        const signalR_URL = `${BACKEND_URL}/api`;
        console.log(`Connecting to SignalR...${signalR_URL}`)
    
        const connection = new signalR.HubConnectionBuilder()
                                .withUrl(signalR_URL)
                                .configureLogging(signalR.LogLevel.Information)
                                .build();
    
        connection.onclose(()  => {
            console.log('SignalR connection disconnected');
            setTimeout(() => connect(), 2000);
        });
    
        connection.on('updated', updatedStock => {
            console.log('Stock updated message received', updatedStock);
            const index = app.stocks.findIndex(s => s.id === updatedStock.id);
            console.log(`${updatedStock.symbol} Old price: ${app.stocks[index].price}, New price: ${updatedStock.price}`);
            app.stocks.splice(index, 1, updatedStock);
        });
    
        connection.start().then(() => {
            console.log("SignalR connection established");
        });
    };
    
    connect();
    
  2. Öffnen Sie ./start/client/index.html, und fügen Sie den folgenden Code anstelle des aktuellen DIV-Elements mit der ID der App ein.

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css"
            integrity="sha256-8B1OaG0zT7uYA572S2xOxWACq9NXYPQ+U5kHPV1bJN4=" crossorigin="anonymous" />
        <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css"
            integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
        <title>Stock Notifications | Enable automatic updates in a web application using Azure Functions and SignalR</title>
    </head>
    
    <body>
        <div id="app" class="container">
            <h1 class="title">Stocks</h1>
            <div id="stocks">
                <div v-for="stock in stocks" class="stock">
                    <transition name="fade" mode="out-in">
                        <div class="list-item" :key="stock.price">
                            <div class="lead">{{ stock.symbol }}: ${{ stock.price }}</div>
                            <div class="change">Change:
                                <span
                                    :class="{ 'is-up': stock.changeDirection === '+', 'is-down': stock.changeDirection === '-' }">
                                    {{ stock.changeDirection }}{{ stock.change }}
                                </span>
                            </div>
                        </div>
                    </transition>
                </div>
            </div>
        </div>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"
            integrity="sha256-chlNFSVx3TdcQ2Xlw7SvnbLAavAQLO0Y/LBiWX04viY=" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/8.0.0/signalr.min.js"></script>
        <script src="bundle.js" type="text/javascript"></script>
    </body>
    </html>
    

    In diesem Markup wird ein Übergangselement eingefügt, durch das „Vue.js“ eine kleine Animation abspielen kann, wenn die Bestandsdaten geändert werden. Wenn eine Aktie aktualisiert wird, wird die Kachel schnell aus- und wieder eingeblendet. Auf diese Weise können Benutzer schnell sehen, welche Aktien sich geändert haben, wenn die Seite mit Aktiendaten gefüllt ist.

  3. Fügen Sie den folgenden Skriptblock direkt über dem Verweis auf bundle.js hinzu, um das SignalR SDK einzuschließen.

    <script src="https://cdn.jsdelivr.net/npm/@aspnet/signalr@1.0.3/dist/browser/signalr.js"></script>
    

Aktualisieren von Client .env

  1. Erstellen Sie eine Umgebungsvariablendatei im start/client-Ordner mit dem Namen .env.

  2. Fügen Sie eine Variable namens BACKEND_URL hinzu, und fügen Sie dessen Wert hinzu, den Sie aus Einheit 5 kopiert haben.

    BACKEND_URL=https://YOUR-FUNTIONS-APP-NAME.azurewebsites.net
    

Erstellen einer Azure Static Web Apps-Ressource und Bereitstellen des Clients

  1. Öffnen Sie das Azure-Portal, um eine neue Azure Static Web Apps-Ressource zu erstellen.

  2. Verwenden Sie die folgenden Informationen, um die Registerkarte Grundlagen der Ressourcenerstellung abzuschließen.

    Name Wert
    Subscription Wählen Sie Ihr Abonnement aus.
    Resource group Verwenden Sie die Ressourcengruppe stock-prototype.
    Name der statischen Web-App Hängen Sie Ihren Namen an client an. Beispiel: client-jamie.
    Typ des Hostingplans Wählen Sie Free aus.
    Bereitstellungsquelle Wählen Sie GitHub aus.
    Organisation Verbindung mit Ihrem GitHub-Konto herstellen
    Repository mslearn-advocates.azure-functions-and-signalr suchen und auswählen.
    Verzweigung Wählen Sie den Mainbranch aus.
    Buildvoreinstellungen Wählen Sie Vue.jsaus.
    App-Speicherort Geben Sie /start/client ein.
    API-Speicherort Lassen Sie dieses Feld leer.
    Ausgabeverzeichnis Geben Sie dist ein.
  3. Wählen Sie Workflowdatei Vorschau anzeigen aus, um die Bereitstellungseinstellungen zu überprüfen. Der Schritt Erstellen und Bereitstellen sollte wie folgt aussehen:

    - name: Build And Deploy
      id: builddeploy
      uses: Azure/static-web-apps-deploy@v1
      with:
        azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_123 }}
        repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
        action: "upload"
        ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
        # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
        app_location: "/solution/client" # App source code path
        api_location: "" # Api source code path - optional
        output_location: "dist" # Built app content directory - optional
        ###### End of Repository/Build Configurations ######
    
  4. Wählen Sie Schließen aus, um die Änderung zu speichern.

  5. Wählen Sie Überprüfen + erstellen und dann Erstellen aus, um die Ressource zu erstellen. Warten Sie auf den Abschluss der Bereitstellung, bevor Sie fortfahren.

  6. Wählen Sie Zur Ressource wechseln, um die neue Azure Static Web App-Ressource zu öffnen.

  7. Kopieren Sie auf der Seite Übersicht den URL-Wert. Dies ist die Basis-URL der bereitgestellten statischen Web-App.

Hinzufügen der BACKEND_URL Variablen zum Repository

Der Workflow muss die BACKEND_URL Umgebungsvariable auf die bereitgestellte Azure Functions-App-Basis-URL aus Einheit 5 festgelegt haben.

  1. Wählen Sie in einem Browser für Ihre GitHub-Verzweigung des Beispiel-Repositorys Einstellungen - >Sicherheit -> Geheimnisse und Variablen -> Aktionen aus.

  2. Wählen Sie Variablen und dann Neue Repositoryvariable aus.

  3. Verwenden Sie die folgende Tabelle, um die Variable zu erstellen:

    Name Wert
    BACKEND_URL Die Basis-URL der bereitgestellten Azure Functions-App. Die URL sollte das Format https://<FUNCTIONS-RESOURCE-NAME>.azurewebsites.net aufweisen
  4. Wählen Sie Variable hinzufügen aus, um die Variable im Repository zu speichern.

GitHub-Bereitstellungsworkflow bearbeiten

  1. Ziehen Sie im Visual Studio Code-Terminal die neue Workflowdatei von Ihrer Verzweigung (Ursprung) nach unten.

    git pull origin main
    
  2. Öffnen Sie die Datei .github/workflows/azure-static-web-apps-*.yml .

  3. Ändern Sie den name Wert oben in der Datei in Client.

  4. Bearbeiten Sie den Schritt Erstellen und Bereitstellen, um die env-Eigenschaft für die BACKEND_URL Umgebungsvariable hinzuzufügen.

    ```yaml
        name: Client - Azure Static Web Apps CI/CD
        
        on:
          push:
            branches:
              - main
          pull_request:
            types: [opened, synchronize, reopened, closed]
            branches:
              - main
        
        jobs:
          build_and_deploy_job:
            if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
            runs-on: ubuntu-latest
            name: Build and Deploy Job
            steps:
    
              - uses: actions/checkout@v3
                with:
                  submodules: true
                  lfs: false
    
              #Debug only - Did GitHub action variable get into workflow correctly?
              - name: Echo
                run: |
                  echo "BACKEND_URL: ${{ vars.BACKEND_URL }}"
    
              - name: Build And Deploy
                id: builddeploy
                uses: Azure/static-web-apps-deploy@v1
                with:
                  azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_123 }}
                  repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
                  action: "upload"
                  ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
                  # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
                  app_location: "/solution/client" # App source code path
                  api_location: "" # Api source code path - optional
                  output_location: "dist" # Built app content directory - optional
                  ###### End of Repository/Build Configurations ######
                env: 
                  BACKEND_URL: ${{ vars.BACKEND_URL }}
    
          close_pull_request_job:
            if: github.event_name == 'pull_request' && github.event.action == 'closed'
            runs-on: ubuntu-latest
            name: Close Pull Request Job
            steps:
              - name: Close Pull Request
                id: closepullrequest
                uses: Azure/static-web-apps-deploy@v1
                with:
                  azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_123 }}
                  action: "close"
        ```
    
  5. Speichern und pushen Sie die Änderungen an das Repository.

    git add .
    git commit -m "Add BACKEND_URL environment variable"
    git push
    
  6. Öffnen Sie die Registerkarte Aktionen im GitHub-Fork-Repository, um die Bereitstellung anzuzeigen.

Aktualisieren von CORS in der Funktions-App

Standardmäßig lassen Funktions-Apps keine CORS-Anforderungen zu. Sie müssen die Funktions-App aktualisieren, um Anforderungen aus der statischen Web-App zuzulassen.

  1. Navigieren Sie im Azure-Portal zur Azure Functions-App, die in Einheit 5 erstellt wurde.

  2. Wählen Sie im Menü auf der linken Seite API - > CORS.

  3. Wählen Sie Access-Control-Allow-Credentials“ aktivieren.

  4. Fügen Sie den Wert hinzu, den Sie für die Ressourcen-URL für statische Web Apps kopiert haben.

    Eigenschaft Wert
    Zulässige Ursprünge Die Basis-URL der bereitgestellten statischen Web-App.
  5. Wählen Sie Speichern aus, um die CORS-Einstellungen zu speichern.

Testen der Bereitstellung des Clients

  1. Verwenden Sie in einem Browser die URL der bereitgestellten statischen Web-App, um den Client zu öffnen.
  2. Öffnen Sie Entwicklertools, um die Konsole anzuzeigen, um zu sehen, wann die SignalR-Daten für aktualisierten Bestand empfangen werden. Denken Sie daran, dass es sich nicht um HTTP-Anforderungen handelt, sodass sie nicht auf der Registerkarte "Netzwerk" angezeigt werden.

Herzlichen Glückwunsch! Sie haben Ihre Bestands-App mit SignalR bereitgestellt!