练习 - 使用 SignalR 服务在 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_STRINGValues 对象中,其中包含终端中列出的值并保存文件。

创建 signalr-open-connection 函数

Web 客户端使用 SignalR 客户端 SDK 来建立与服务器的连接。 SDK 通过名为 signalr-open-connection 的函数检索连接,以便连接到服务。

  1. 按 F1 打开 Visual Studio Code 命令面板。

  2. 搜索并选择“Azure Functions: Create Function 命令。

  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: Create Function 命令。

  3. 选择函数应用的位置作为 start/server

  4. 出现提示时,请提供以下信息。

    名称
    模板 Azure Cosmos DB 触发器
    名称 signalr-send-message
    Cosmos DB 连接字符串 COSMOSDB_CONNECTION_STRING
    要监视的数据库名称 stocksdb
    集合名称 stocks
    检查是否存在,并自动创建租约集合

    刷新 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 门户以创建新的函数应用。

  2. 使用以下信息填写资源创建页面上的“基本信息”选项卡

    名称
    资源组 创建新的资源组名称 stock-prototype
    函数应用名称 将名称追加到 api 后面。 例如 api-jamie
    代码或容器 选择“代码”
    运行时堆栈 选择“Node.js”
    版本 选 择Node.js 的 LTS 版本。
    区域 选择附近的区域。
    操作系统 选择“Linux”。
    承载 选择“消耗计划”
  3. 不要填写任何其他选项卡,然后选择“查看 + 创建”,然后选择“创建”。 等待部署完成,然后继续。

  4. 选择“转到资源”以打开新的函数应用。

配置 GitHub 部署

将新的函数应用连接到 GitHub 存储库以启用持续部署。 在生产环境中,在将代码更改交换到生产环境之前,应将代码更改部署到过渡槽。

  1. 在新函数应用的 Azure 门户页中,从左侧菜单中选择“部署中心”

  2. 选择 GitHub

  3. 使用以下信息完成部署配置。

    名称
    组织 选择你的 GitHub 帐户。
    存储库 搜索并选择 mslearn-advocates.azure-functions-and-signalr
    分支 选择主分支。
    工作流选项 选择“添加工作流...”
    身份验证类型 选择“用户分配的标识”
    订阅 选择与页面顶部相同的订阅。
    标识 选择“新建”。
  4. 选择部分顶部的“保存”以保存设置。 这会在分叉存储库中创建新的工作流文件。

  5. 此部署配置在存储库中创建 GitHub Actions 工作流文件。 需要更新工作流文件,以便为函数应用使用正确的包路径。

编辑 GitHub 部署工作流

  1. 在 Visual Studio Code 终端中,从分支(源)中拉取新的工作流文件。

    git pull origin main
    

    这应将新文件夹放在 .github,其中包含工作流文件的路径:`.github/workflows/main_RESOURCE_NAME.yml,其中 RESOURCE_NAME 是 Azure Functions 应用名称。

  2. 打开工作流文件。

  3. 将文件顶部的 name 值更改为 Server

  4. 由于源存储库在子目录中具有 Azure Functions 应用,因此操作文件需要更改才能反映这一点。 在 env 节中,添加名为 PACKAGE_PATH 的新变量以使用包路径。

    env:
      PACKAGE_PATH: 'start/server'
    
  5. 查找“使用 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
    
  6. 找到“用于部署的 Zip 项目”步骤,并将内容替换为以下 YAML,以使用包子目录路径。

    - name: Upload artifact for deployment job
      uses: actions/upload-artifact@v3
      with:
        name: node-app
        path: release.zip
    

    zip 文件放置在存储库的根目录中,因此需要 ../ 值才能将 zip 文件放在根目录。

  7. 保存文件并将更改提交到存储库。

    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 中工作时,需要为 BACKEND_URL 值更新客户端 .env 文件。
  3. 在浏览器中打开 URL 以测试 API 函数。
  4. /api/getStocks 追加到浏览器中的 URL,然后按 Enter。 应会看到包含股票数据的 JSON 数组。

你已更新服务器代码以使用 SignalR 返回股票,并且已部署到函数应用。 接下来,你将更新客户端以使用 SignalR 接收更新。