Esercizio: usare un account di archiviazione per ospitare un sito Web statico

Completato

Ora che l'API è distribuita nel cloud, in qualità di tecnico di Tailwind Traders si deve aggiornare il codice client e distribuirlo per supportare i messaggi SignalR in arrivo per Funzioni di Azure.

Aggiornare l'applicazione client

  1. In Visual Studio Code aprire ./start/client/src/index.js e sostituire tutto il codice per l'ascolto dei messaggi SignalR. Il codice ottiene l'elenco di titoli iniziale con una richiesta HTTP e quindi rimane in ascolto degli aggiornamenti dalla connessione SignalR. Quando un titolo viene aggiornato, il client aggiorna il prezzo del titolo nell'interfaccia utente.

    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. Aprire ./start/client/index.html e incollare il codice seguente al posto dell'elemento DIV corrente con l'ID dell'app.

    <!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>
    

    Questo markup include un elemento di transizione, che consente a Vue.js di eseguire un'animazione poco evidente quando vengono modificati i dati dei titoli azionari. Quando un titolo viene aggiornato, il riquadro si dissolve e torna rapidamente a essere visualizzato. In questo modo, se la pagina è piena di dati dei titoli azionari, gli utenti possono vedere facilmente quali sono stati modificati.

  3. Aggiungere il blocco di script seguente appena sopra il riferimento a bundle.js per includere SignalR SDK.

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

Aggiornare il file ENV del client

  1. Creare un file di variabili di ambiente nella cartella start/client con nome .env.

  2. Aggiungere una variabile denominata BACKEND_URL e aggiungerne il valore copiato dall'unità 5.

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

Creare una risorsa di App Web statiche di Azure e distribuire il client

  1. Aprire il portale di Azure per creare una nuova risorsa di App Web statiche di Azure.

  2. Usare le informazioni seguenti per completare la creazione di risorse nella scheda Informazioni di base.

    Nome Valore
    Subscription Selezionare la propria sottoscrizione.
    Gruppo di risorse Usare il gruppo di risorse stock-prototype.
    Nome app Web statica Anteporre il nome a client. Ad esempio: client-jamie.
    Tipo di piano di hosting Selezionare Gratuito.
    Origine della distribuzione Selezionare GitHub.
    Organizzazione Selezionare l'account GitHub
    Repository Cercare e selezionare mslearn-advocates.azure-functions-and-signalr.
    Ramo Selezionare il ramo main.
    Build Presets (Set di impostazioni di compilazione) Selezionare Vue.js.
    App location (Percorso app) Immetti /start/client.
    Percorso API Lasciare vuoto.
    Percorso di output Immetti dist.
  3. Selezionare Anteprima file del flusso di lavoro per esaminare le impostazioni di distribuzione. Il passaggio Compilazione e distribuzione dovrebbe essere simile al seguente:

    - 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. Selezionare Chiudi per salvare la modifica.

  5. Selezionare Rivedi e crea e quindi selezionare Crea per creare la risorsa. Attendere il completamento della distribuzione prima di continuare.

  6. Selezionare Vai alla risorsa per aprire la nuova risorsa app Web statica di Azure.

  7. Nella pagina Panoramica copiare il valore URL. Si tratta dell'URL di base dell'app Web statica distribuita.

Aggiungere la variabile BACKEND_URL al repository

Il flusso di lavoro deve avere la variabile di ambiente BACKEND_URL impostata sull'URL di base dell'app Funzioni di Azure distribuito dall'unità 5.

  1. In un browser per il fork GitHub del repository di esempio selezionare Impostazioni -> Sicurezza -> Segreti e variabili -> Azioni.

  2. Selezionare Variabili e quindi selezionare Nuova variabile del repository.

  3. Usare la tabella seguente per creare la variabile :

    Nome Valore
    BACKEND_URL URL di base dell'app Funzioni di Azure distribuita. Il formato dell'URL deve essere https://<FUNCTIONS-RESOURCE-NAME>.azurewebsites.net
  4. Selezionare Aggiungi variabile per salvare la variabile nel repository.

Modificare il flusso di lavoro di distribuzione di GitHub

  1. Nel terminale di Visual Studio Code eseguire il pull del nuovo file del flusso di lavoro dal fork (origine).

    git pull origin main
    
  2. Apri il file .github/workflows/azure-static-web-apps-*.yml.

  3. Modificare il valore name nella parte superiore del file in Client.

  4. Modificare il passaggio Compilazione e distribuzione per aggiungere la proprietà env per la variabile di ambiente BACKEND_URL.

    ```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. Salvare ed eseguire il push delle modifiche nel repository.

    git add .
    git commit -m "Add BACKEND_URL environment variable"
    git push
    
  6. Aprire la scheda Actions nel repository fork di GitHub per controllare la distribuzione.

Aggiornare CORS nell'app per le funzioni

Per impostazione predefinita, le app per le funzioni non consentono le richieste CORS. È necessario aggiornare l'app per le funzioni per consentire le richieste dall'app Web statica.

  1. Nel portale di Azure passare all'app Funzioni di Azure creata nell'unità 5.

  2. Nel menu a sinistra selezionare API -> CORS.

  3. Selezionare Abilita Access-Control-Allow-Credentials.

  4. Aggiungere il valore copiato per l'URL della risorsa App Web statiche.

    Proprietà valore
    Origini consentite URL di base dell'app Web statica distribuita.
  5. Selezionare Salva per salvare le impostazioni CORS.

Testare la distribuzione del client

  1. In un browser usare l'URL dell'app Web statica distribuita per aprire il client.
  2. Aprire gli Strumenti di sviluppo per controllare la console per verificare quando vengono ricevuti i dati di SignalR per i titoli aggiornati. Tenere presente che queste non sono richieste HTTP, quindi non verranno visualizzate nella scheda Rete.

Complimenti. È stata distribuita l'app per i titoli migliorata con SignalR.