演習 - SignalR Service を使用して Web アプリケーションの自動更新を有効にする

完了

このプロトタイプに SignalR を追加するには、次のものを作成する必要があります。

  • Azure SignalR リソース
  • SignalR をサポートするいくつかの新しい関数
  • SignalR をサポートするようにクライアントを更新する

SignalR リソースを作成する

Azure SignalR リソースを作成する必要があります。

  1. ターミナルに戻り、SignalR リソースを作成します。

  2. setup-resources サブディレクトリに移動し、リソースを作成します。

    cd stock-prototype/setup-resources && bash create-signalr-resources.sh & cd ..
    
  3. SignalR リソースの接続文字列をコピーします。 これは、サーバー コードを更新するために必要です。

    リソースの種類 環境変数
    Azure SignalR SIGNALR_CONNECTION_STRING と呼ばれます

サーバー構成環境変数を更新する

./start/server/local.settings.json で、ターミナルに一覧表示されている値を使用して、SIGNALR_CONNECTION_STRING という名前の Values オブジェクトに変数を追加し、ファイルを保存します。

signalr-open-connection 関数を作成する

Web クライアントでは SignalR クライアント SDK を使用して、サーバーへの接続を確立します。 SDK では、signalr-open-connection という名前の関数を介して接続を取得し、サービスに接続します。

  1. F1 キーを押して、Visual Studio Code のコマンド パレットを開きます。

  2. [Azure Functions: 関数の作成] コマンドを検索して選択します。

  3. [既定値の設定] を選択し、[開始/サーバー] を選択して関数アプリの場所を設定します。

  4. [VS Code で使用するためにプロジェクトを初期化しますか?] と尋ねられたら、[はい] を選択します。

  5. 入力を求められたら、次の情報を指定します。

    名前
    テンプレート HTTP トリガー
    名前 signalr-open-connection

    signalr-open-connection.ts という名前のファイルが、./start/server/src/functions で使用できるようになりました。

  6. signalr-open-connection.ts を開き、すべてを次のコードに置き換えます。

    import { app, input } from '@azure/functions';
    
    const inputSignalR = input.generic({
        type: 'signalRConnectionInfo',
        name: 'connectionInfo',
        hubName: 'default',
        connectionStringSetting: 'SIGNALR_CONNECTION_STRING',
    });
    
    app.http('open-signalr-connection', {
        authLevel: 'anonymous',
        handler: (request, context) => {
            return { body: JSON.stringify(context.extraInputs.get(inputSignalR)) }
        },
        route: 'negotiate',
        extraInputs: [inputSignalR]
    });
    

    SignalR 接続情報が関数から返されます。

signalr-send-message 関数を作成する

  1. F1 キーを押して、Visual Studio Code のコマンド パレットを開きます。

  2. [Azure Functions: 関数の作成] コマンドを検索して選択します。

  3. [開始/サーバー] として関数アプリの場所を選択します。

  4. 入力を求められたら、次の情報を指定します。

    名前
    テンプレート Azure Cosmos DB のトリガー
    名前 signalr-send-message
    Cosmos DB の接続文字列 COSMOSDB_CONNECTION_STRING
    監視対象のデータベース名 stocksdb
    コレクション名 stocks
    有無を確認し、リース コレクションを自動的に作成する true

    Visual Studio Code でエクスプローラー ウィンドウを更新し、更新内容を確認します。 signalr-open-connection という名前のファイルが、./start/server/src/functions で使用できるようになりました。

  5. signalr-send-message.ts を開き、すべてを次のコードに置き換えます。

    import { app, output, CosmosDBv4FunctionOptions, InvocationContext } from "@azure/functions";
    
    const goingOutToSignalR = output.generic({
        type: 'signalR',
        name: 'signalR',
        hubName: 'default',
        connectionStringSetting: 'SIGNALR_CONNECTION_STRING',
    });
    
    export async function dataToMessage(documents: unknown[], context: InvocationContext): Promise<void> {
    
        try {
    
            context.log(`Documents: ${JSON.stringify(documents)}`);
    
            documents.map(stock => {
                // @ts-ignore
                context.log(`Get price ${stock.symbol} ${stock.price}`);
                context.extraOutputs.set(goingOutToSignalR,
                    {
                        'target': 'updated',
                        'arguments': [stock]
                    });
            });
        } catch (error) {
            context.log(`Error: ${error}`);
        }
    }
    
    const options: CosmosDBv4FunctionOptions = {
        connection: 'COSMOSDB_CONNECTION_STRING',
        databaseName: 'stocksdb',
        containerName: 'stocks',
        createLeaseContainerIfNotExists: true,
        feedPollDelay: 500,
        handler: dataToMessage,
        extraOutputs: [goingOutToSignalR],
    };
    
    app.cosmosDB('send-signalr-messages', options);
    
  • 受信データを定義する: comingFromCosmosDB オブジェクトは、変更を監視する Cosmos DB トリガーを定義します。
  • 送信トランスポートを定義する: goingOutToSignalR オブジェクトは、同じ SignalR 接続を定義します。 hubName は同じハブ default です。
  • データをトランスポートに接続する: dataToMessage は、stocks テーブル内の "変更された" 項目を取得し、同じハブ default を使用する extraOutputs を使用して、SignalR 経由で、変更された各項目を個別に送信します。
  • アプリに接続する: app.CosmosDB は、関数名 send-signalr-messages にバインドを結び付けます。

変更をコミットして GitHub にプッシュする

  1. ターミナルで、変更をリポジトリにコミットします。

    git add .
    git commit -m "Add SignalR functions"
    git push
    

signalr-send-message 関数を作成する

Azure に、新しい関数コードを公開できる関数アプリと、関連するリソースを作成します。

  1. Azure portal を開き、新しい関数アプリを作成します。

  2. 次の情報を使用して、リソース作成の [基本] タブに入力します。

    名前
    リソース グループ 新しいリソース グループ名 stock-prototype を作成します。
    関数アプリ名 自分の名前を api の後ろに追加します。 たとえば、api-jamie のようにします。
    コードまたはコンテナー [コード] を選択します。
    ランタイム スタック [Node.js] を選択します。
    バージョン Node.js の LTS バージョンを選択します。
    リージョン 近くのリージョンを選択します。
    オペレーティング システム [Linux] を選択します。
    ホスティング [従量課金プラン] を選択します。
  3. 他のタブには入力せずに、[確認と作成][作成] の順に選択します。 デプロイが完了するまで待ってから次に進みます。

  4. [リソースに移動] を選択して、新しい関数アプリを開きます。

GitHub デプロイを構成する

新しい関数アプリを GitHub リポジトリに接続して、継続的デプロイを有効にします。 運用環境では、代わりに、コード変更を運用環境にスワップする前にステージング スロットにデプロイします。

  1. 新しい関数アプリの Azure portal ページで、左側のメニューから [デプロイ センター] を選択します。

  2. GitHubソース を選択します。

  3. 次の情報を使用して、デプロイ構成を完了します。

    名前
    Organization GitHub アカウントを選択します。
    リポジトリ mslearn-advocates.azure-functions-and-signalr を検索して選択します。
    [Branch]\(ブランチ) main ブランチを選択します。
    ワークフロー オプション [ワークフローの追加...] を選択します。
    認証の種類 [ユーザー割り当て ID] を選択します。
    サブスクリプション ページの上部に表示されているものと同じサブスクリプションを選択します。
    ID [新規作成] を選択します。
  4. セクションの上部にある [保存] を選択して設定を保存します。 これにより、フォークされたリポジトリに新しいワークフロー ファイルが作成されます。

  5. このデプロイ構成により、リポジトリに GitHub Actions ワークフロー ファイルが作成されます。 関数アプリの正しいパッケージ パスを使用するように、ワークフロー ファイルを更新する必要があります。

この時点で、Azure のリソース グループに作成されたユーザー割り当てマネージド ID の構成が間違っているため、GitHub デプロイでエラーが発生する可能性があります。

マネージド ID を更新する

  1. Azure portal の新しい関数アプリ ページで、[概要]>[基本] でリソース グループを選び、[リソース] でマネージド ID を選びます。 このマネージド ID は、GitHub デプロイを有効にしたときに Functions によって作成されました。
  2. [マネージド ID] ページで、[設定]>[フェデレーション資格情報] を選択し、既存の資格情報を選びます。
  3. [Github アカウントに接続]で、[エンティティ] の設定を [環境] に変更し、[環境]Production を入力します。
  4. [更新] を選択して資格情報を更新します。

GitHub デプロイ ワークフローを編集する

  1. Visual Studio Code ターミナルで、フォーク (origin) から新しいワークフロー ファイルをプルダウンします。

    git pull origin main
    

    これにより、ワークフロー ファイルへのパスを含む新しいフォルダー .github/workflows/main_RESOURCE_NAME.yml (RESOURCE_NAME は関数アプリ名) が .github に配置されます。

  2. ワークフロー ファイルを開き、ファイルの上部にある name の値を Server に変更します。

  3. ソース リポジトリには、サブディレクトリに関数アプリがあるため、アクション ファイルを変更してそれを反映する必要があります。 env セクションで、パッケージ パスを使用する PACKAGE_PATH という名前の新しい変数を追加します。

    env:
      PACKAGE_PATH: 'start/server'
    
  4. パッケージのサブディレクトリ パスも使用するために、Npm を使用してプロジェクトの依存関係を解決するステップを見つけて、その内容を次の YAML に置き換えます。 重要な変更は、env.PACKAGE_PATH 変数を含める pushd コマンド内のパスです。

    - name: 'Resolve Project Dependencies Using Npm'
      shell: bash
      run: |
        pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/${{ env.PACKAGE_PATH }}'
        npm install
        npm run build --if-present
        npm run test --if-present
        popd
    
  5. パッケージのサブディレクトリ パスも使用するために、デプロイの ZIP 成果物ステップを見つけて、その内容を次の YAML に置き換えます。

    - name: Zip artifact for deployment
      run: |
        pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/${{ env.PACKAGE_PATH }}'
        zip -r release.zip .
        popd
        cp ./${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/${{ env.PACKAGE_PATH }}/release.zip ./release.zip
    

    ZIP ファイルはリポジトリのルートに配置されるため、ZIP ファイルをルートに配置するには、../ 値が必要です。

  6. ファイルを保存し、変更をリポジトリにコミットします。

    git add .
    git commit -m "Update deployment workflow to use package path"
    git push
    

    この変更によって、ワークフローの実行がトリガーされます。 GitHub のフォークの Actions セクションからワークフローを確認できます。

API 関数の環境変数を構成する

  1. Azure portal で関数アプリを見つけ、[設定]>[構成] を選択し、[新しいアプリケーションの設定] を選択します。

  2. Cosmos DB と SignalR の接続文字列の設定を入力します。 値は、start/server フォルダーの local.settings.json 内にあります。

    名前
    COSMOSDB_CONNECTION_STRING Cosmos DB アカウントの接続文字列。
    SIGNALR_CONNECTION_STRING SignalR アカウントの接続文字列。
  3. [保存] を選択して設定を保存します。

API 関数のデプロイをテストする

  1. Azure portal で、[概要] を選択し、[URL] を選択して、ブラウザーでアプリを開きます。
  2. URL をコピーします。ユニット 7 の作業時に BACKEND_URL 値のクライアント .env ファイルを更新する際、これが必要になります。
  3. ブラウザーで URL を開き、API 関数をテストします。
  4. ブラウザーの URL に /api/getStocks を追加し、Enter キーを押します。 株価データを含む JSON 配列が表示されます。

SignalR で株価を返すようにサーバー コードを更新し、関数アプリにデプロイしました。 次は、SignalR を使用して更新プログラムを受け取るようにクライアントを更新します。