練習 - 在 Web 應用程式中使用 SignalR Service 來啟用自動更新

已完成

若要將此 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_STRINGValues 物件,並儲存檔案。

建立 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 資料表中變更的項目,並透過採用相同中樞 defaultextraOutputs 經由 SignalR 個別傳送每個變更的項目。
  • 連線到應用程式app.CosmosDB 會將繫結程序繫結至函式名稱 send-signalr-messages

認可變更並推送至 GitHub

  1. 在終端機中,認可存放庫的變更。

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

建立 signalr-send-message 函式

在 Azure 中建立函式應用程式和相關資源,您可以在其中發布新的函式程式碼。

  1. 開啟 Azure 入口網站,以建立新的函數應用程式。

  2. 使用下列資訊來完成資源建立 [基本資料] 索引標籤。

    名稱
    資源群組 建立新的資源群組名稱 stock-prototype
    函數應用程式名稱 將名稱貼到 api。 例如: api-jamie
    程式碼或容器 選取 [程式碼]
    執行階段堆疊 選取 [Node.js]
    版本 選取 LTS 版本的 Node.js。
    區域 選取接近您的區域。
    作業系統 選取 [Linux]
    裝載 選取 [耗用量方案]
  3. 請勿填寫任何其他索引標籤,然後選取 [檢閱 + 建立],然後選取 [建立]。 等候部署完成,再繼續進行操作。

  4. 選取 [前往資源],以開啟新的函式應用程式。

設定 GitHub 部署

將新的函式應用程式連線至 GitHub 存放庫,以啟用持續部署。 在生產環境中,您會改為將程式碼變更部署到預備位置,再將它們交換至生產環境。

  1. 在新函式應用程式的 Azure 入口網站頁面中,從左側功能表中選取 [部署中心]

  2. 選取 GitHub 來源

  3. 使用下列資訊來完成部署設定。

    名稱
    組織 連接您的 GitHub 帳戶。
    存放庫 搜尋並選取 mslearn-advocates.azure-functions-and-signalr
    分行 選取 main 分支。
    工作流程選項 選取 [新增工作流程...]
    驗證類型 選取使用者指派的身分識別
    訂用帳戶 選取頁面頂端所見的相同訂用帳戶。
    身分識別 選取 [新建]
  4. 選取區段頂端的 [儲存] 以儲存設定。 這會在您的分支存放庫中建立新的工作流程檔案。

  5. 此部署設定會在存放庫中建立 GitHub Actions 工作流程檔案。 您必須更新工作流程檔案,以針對函式應用程式使用正確的套件路徑。

此時,GitHub 部署可能會因為 Azure 資源群組中建立的使用者指派受控識別設定錯誤而產生錯誤。

更新此受控識別

  1. 在 Azure 入口網站的新函數應用程式頁面中,選取 [概觀] > [基本資訊] 中的資源群組,然後在 [資源] 底下選取該受控識別。 啟用 GitHub 部署時,Azure Functions 就會建立此受控識別。
  2. 在 [受控識別] 頁面中,選取 [設定] > [同盟認證],然後選取現有的認證。
  3. 在 [連線 Github 帳戶]中,將 [實體] 的設定變更為 [環境],然後為環境輸入 Production
  4. 選取 [更新] 以更新此認證。

編輯 GitHub 部署工作流程

  1. 在 Visual Studio Code 終端機中,從分支提取新的工作流程檔案 (原點)。

    git pull origin main
    

    這應該會將新資料夾放在 .github,其中包含工作流程檔案的路徑:.github/workflows/main_RESOURCE_NAME.yml,其中 RESOURCE_NAME 是函數應用程式名稱。

  2. 開啟工作流程檔案,並將檔案頂端的值 name 變更為 Server

  3. 因為來源存放庫在子目錄中有函數應用程式,因此動作檔案必須變更才能反映該情況。 在 [env] 區段中,新增名為 PACKAGE_PATH 的新變數,以使用封裝路徑。

    env:
      PACKAGE_PATH: 'start/server'
    
  4. 尋找使用 Npm 解決專案相依性步驟,並將內容取代為下列 YAML,以使用封裝子目錄路徑。 重大變更是 pushd 命令中要包含 env.PACKAGE_PATH 變數的路徑。

    - 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 上分支的 [動作] 區段觀看工作流程。

設定 API 函式的環境變數

  1. 在 Azure 入口網站中,找出函數應用程式,然後選取 [設定] > [設定],然後選取 [新增應用程式設定]

  2. 輸入 Cosmos DB 和 SignalR 連接字串的設定。 您可以在 start/server 資料夾中的 local.settings.json 中找到值。

    名稱
    COSMOSDB_CONNECTION_STRING Cosmos DB 帳戶的連接字串。
    SIGNALR_CONNECTION_STRING SignalR 帳戶的連接字串。
  3. 選取 [儲存] 以儲存設定。

測試 API 函式的部署

  1. 在 Azure 入口網站中,選取 [概觀],然後選取 [URL] 以在瀏覽器中開啟應用程式。
  2. 複製 URL,當您在單元 7 中工作時,需要更新用戶端 .env 檔案以取得 BACKEND_URL 值。
  3. 在瀏覽器中開啟 URL,以測試 API 函式。
  4. /api/getStocks 附加至瀏覽器中的 URL,然後按 Enter。 您應該會看到含有庫存資料的 JSON 陣列。

您已更新伺服器程式碼以使用 SignalR 傳回庫存,並已部署至函式應用程式。 接下來,您將更新用戶端以使用 SignalR 接收更新。