练习 - 使用 SignalR 服务在 Web 应用程序中启用自动更新
若要将 SignalR 添加到此原型,需要创建:
- Azure SignalR 资源
- 支持 SignalR 的一些新函数
- 更新客户端以支持 SignalR
创建 SignalR 资源
需要创建 Azure SignalR 资源。
返回到终端以创建 SignalR 资源。
导航到
setup-resources
子目录以创建资源。cd stock-prototype/setup-resources && bash create-signalr-resources.sh & cd ..
复制 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 的函数检索连接,以便连接到服务。
按 F1 打开 Visual Studio Code 命令面板。
搜索并选择“Azure Functions: Create Function 命令。
选择“设置默认”然后选择“启动/服务器”,以设置函数应用的位置。
当系统询问初始化项目以用于 VS Code?时,请选择“是”。
出现提示时,请提供以下信息。
名称 值 模板 HTTP 触发器 名称 signalr-open-connection 名为 signalr-open-connection.ts 的文件现已在
./start/server/src/functions
上提供。打开 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
函数
按 F1 打开 Visual Studio Code 命令面板。
搜索并选择“Azure Functions: Create Function 命令。
选择函数应用的位置作为 start/server。
出现提示时,请提供以下信息。
名称 值 模板 Azure Cosmos DB 触发器 名称 signalr-send-message
Cosmos DB 连接字符串 COSMOSDB_CONNECTION_STRING 要监视的数据库名称 stocksdb
集合名称 stocks
检查是否存在,并自动创建租约集合 是 刷新 Visual Studio Code 中的资源管理器窗口以查看更新。 名为 signalr-open-connection 的文件现已在
./start/server/src/functions
上提供。打开 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
在终端中,将更改提交到存储库。
git add . git commit -m "Add SignalR functions" git push
创建 signalr-send-message
函数
在 Azure 中创建一个函数应用和相关资源,可以将新函数代码发布到其中。
打开 Azure 门户以创建新的函数应用。
使用以下信息填写资源创建页面上的“基本信息”选项卡。
名称 值 资源组 创建新的资源组名称 stock-prototype
。函数应用名称 将名称追加到 api
后面。 例如api-jamie
。代码或容器 选择“代码”。 运行时堆栈 选择“Node.js”。 版本 选 择Node.js 的 LTS 版本。 区域 选择附近的区域。 操作系统 选择“Linux”。 承载 选择“消耗计划”。 不要填写任何其他选项卡,然后选择“查看 + 创建”,然后选择“创建”。 等待部署完成,然后继续。
选择“转到资源”以打开新的函数应用。
配置 GitHub 部署
将新的函数应用连接到 GitHub 存储库以启用持续部署。 在生产环境中,在将代码更改交换到生产环境之前,应将代码更改部署到过渡槽。
在新函数应用的 Azure 门户页中,从左侧菜单中选择“部署中心”。
选择 GitHub 的源。
使用以下信息完成部署配置。
名称 值 组织 选择你的 GitHub 帐户。 存储库 搜索并选择 mslearn-advocates.azure-functions-and-signalr
。分支 选择主分支。 工作流选项 选择“添加工作流...”。 身份验证类型 选择“用户分配的标识”。 订阅 选择与页面顶部相同的订阅。 标识 选择“新建”。 选择部分顶部的“保存”以保存设置。 这会在分叉存储库中创建新的工作流文件。
此部署配置在存储库中创建 GitHub Actions 工作流文件。 需要更新工作流文件,以便为函数应用使用正确的包路径。
此时,GitHub 部署可能会生成错误,因为在你的 Azure 资源组中创建的用户分配的托管标识的配置不正确。
更新托管标识
- 在 Azure 门户中的新函数应用页中,在“概述”>“概要”中选择你的资源组,然后在“资源”下选择托管标识。 启用 GitHub 部署时,Functions 会创建此托管标识。
- 在“托管标识”页中,选择“设置”>“联合凭据”,然后选择现有凭据。
- 在“连接 Github 帐户”中,将“实体”的设置更改为“环境”并在“环境”中输入
Production
。 - 选择“更新”以更新凭据。
编辑 GitHub 部署工作流
在 Visual Studio Code 终端中,从分支(源)中拉取新的工作流文件。
git pull origin main
这应会在 .github 处放置一个新文件夹,其中包含你的工作流文件的路径:
.github/workflows/main_RESOURCE_NAME.yml
,其中RESOURCE_NAME
是函数应用名称。打开工作流文件并将文件顶部的
name
值更改为Server
。由于源存储库在子目录中具有函数应用,因此操作文件需要更改才能反映这一点。 在 env 节中,添加名为
PACKAGE_PATH
的新变量以使用包路径。env: PACKAGE_PATH: 'start/server'
查找“使用 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
找到“用于部署的 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 文件放在根目录。保存文件并将更改提交到存储库。
git add . git commit -m "Update deployment workflow to use package path" git push
此更改将触发要运行的工作流。 可以从 GitHub 上的分支“操作”部分观看工作流。
为 API 函数配置环境变量
在 Azure 门户中,找到你的函数应用并选择“设置”>“配置”,然后选择“新建应用程序设置”。
输入 Cosmos DB 和 SignalR 连接字符串的设置。 可以在
start/server
文件夹中的local.settings.json
中找到这些值。名称 值 COSMOSDB_CONNECTION_STRING Cosmos DB 帐户的连接字符串。 SIGNALR_CONNECTION_STRING SignalR 帐户的连接字符串。 选择保存,保存这些设置。
测试 API 函数的部署
- 在 Azure 门户中,选择“概述”,并选择“URL”以在浏览器中打开应用。
- 复制 URL,在单元 7 中工作时,需要为
BACKEND_URL
值更新客户端.env
文件。 - 在浏览器中打开 URL 以测试 API 函数。
- 将
/api/getStocks
追加到浏览器中的 URL,然后按 Enter。 应会看到包含股票数据的 JSON 数组。
你已更新服务器代码以使用 SignalR 返回股票,并且已部署到函数应用。 接下来,你将更新客户端以使用 SignalR 接收更新。