快速入門:使用 Azure Functions 和 SignalR Service 透過 C 建立顯示 GitHub 星號計數的應用程式#
在本文中,您將瞭解如何使用 SignalR Service 和 Azure Functions 來建置具有 C# 的無伺服器應用程式,以將訊息廣播至用戶端。
必要條件
本快速入門需要下列必要條件:
- Visual Studio Code 或其他程式碼編輯器。 如果您尚未安裝 Visual Studio Code, 請在這裡下載 Visual Studio Code。
- Azure 訂用帳戶。 如果您沒有 Azure 訂用帳戶, 請在開始之前免費 建立一個訂用帳戶。
- Azure Functions Core Tools
- .NET Core SDK
建立 Azure SignalR 服務實例
在本節中,您會建立基本 Azure SignalR 執行個體,以用於您的應用程式。 下列步驟會使用 Azure 入口網站來建立新的執行個體,但您也可以使用 Azure CLI。 如需詳細資訊,請參閱 Azure SignalR Service CLI 參考中的 az signalr create 命令。
- 登入 Azure 入口網站。
- 在頁面的左側,選取 [+ 建立資源]。
- 在 [建立資源] 頁面上的 [搜尋服務和市集] 文字方塊中,輸入 signalr,然後從清單中選取 [SignalR Service]。
- 在 [SignalR Service] 頁面上,選取 [建立]。
- 在 [基本] 索引標籤上,您會輸入新 SignalR Service 執行個體的重要資訊。 輸入下列值:
欄位 | 建議的值 | 描述 |
---|---|---|
訂用帳戶 | 選擇您的訂用帳戶 | 選取您要用來建立新 SignalR Service 執行個體的訂用帳戶。 |
資源群組 | 建立名為 SignalRTestResources 的新資源群組 | 選取或建立 SignalR 資源的資源群組。 針對本教學課程建立新的資源群組,而不是使用現有的資源群組,會很有用。 若要在完成本教學課程之後釋出資源,請刪除資源群組。 刪除資源群組同時會刪除群組所屬的所有資源。 此動作無法復原。 刪除資源群組之前,請確定其不包含您想要保留的資源。 如需詳細資訊,請參閱 使用資源群組來管理您的 Azure 資源。 |
資源名稱 | testsignalr | 輸入要對 SignalR 資源使用的唯一資源名稱。 如果您的區域中已採用 testsignalr,請新增數字或字元,直到成為唯一的名稱為止。 名稱必須是 1 到 63 個字元的字串,而且只能包含數字、字母和連字號 ( - ) 字元。 名稱的開頭或結尾不能是連字號字元,且連續連字號字元無效。 |
區域 | 選擇您的區域 | 選取新 SignalR Service 執行個體的適當區域。 Azure SignalR Service 目前不適用於所有區域。 如需詳細資訊,請參閱 Azure SignalR 區域可用性 |
定價層 | 選取 [變更],然後選擇 [免費 (僅限開發/測試)]。 選擇 [選取] 來確認您選擇的定價層。 | Azure SignalR Service 有三個定價層:免費、標準和進階。 除非必要條件中另有說明,否則教學課程會使用 [免費] 層。 如需有關階層與定價之間功能差異的詳細資訊,請參閱 Azure SignalR Service 定價 |
服務模式 | 選擇適當的服務模式 | 當您在 Web 應用程式中裝載 SignalR 中樞邏輯並使用 SignalR 服務做為 Proxy 時,請使用 [預設值]。 當您使用 Azure Functions 之類的無伺服器技術來裝載 SignalR 中樞邏輯時,請使用 [無伺服器]。 [傳統] 模式僅適用於回溯相容性,不建議使用。 如需詳細資訊,請參閱 Azure SignalR Service 中的服務模式。 |
您不需要針對 SignalR 教學課程變更 [網路] 和 [標籤] 索引標籤上的設定。
- 選取 [基本] 索引標籤底部的 [檢閱 + 建立] 按鈕。
- 在 [檢閱 + 建立] 索引標籤上,檢閱這些值,然後選取 [建立]。 需要數分鐘才能完成部署。
- 部署完成後,請選取 [移至資源] 按鈕。
- 在 SignalR 資源頁面上,從左側功能表的 [設定] 底下選取 [金鑰]。
- 複製主索引鍵的 [連接字串]。 稍後在本教學課程中,您需要此連接字串來設定您的應用程式。
在本機設定並執行 Azure 函式
您需要此步驟的 Azure Functions Core Tools。
建立空的目錄,並使用命令行變更至目錄。
初始化新專案。
使用程式代碼編輯器,建立名稱 為Function.cs的新檔案。 將下列程式代碼新增至 Function.cs:
using System; using System.IO; using System.Linq; using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.Azure.WebJobs.Extensions.SignalRService; using Newtonsoft.Json; namespace CSharp { public static class Function { private static HttpClient httpClient = new HttpClient(); private static string Etag = string.Empty; private static string StarCount = "0"; [FunctionName("index")] public static IActionResult GetHomePage([HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequest req, ExecutionContext context) { var path = Path.Combine(context.FunctionAppDirectory, "content", "index.html"); return new ContentResult { Content = File.ReadAllText(path), ContentType = "text/html", }; } [FunctionName("negotiate")] public static SignalRConnectionInfo Negotiate( [HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req, [SignalRConnectionInfo(HubName = "serverless")] SignalRConnectionInfo connectionInfo) { return connectionInfo; } [FunctionName("broadcast")] public static async Task Broadcast([TimerTrigger("*/5 * * * * *")] TimerInfo myTimer, [SignalR(HubName = "serverless")] IAsyncCollector<SignalRMessage> signalRMessages) { var request = new HttpRequestMessage(HttpMethod.Get, "https://api.github.com/repos/azure/azure-signalr"); request.Headers.UserAgent.ParseAdd("Serverless"); request.Headers.Add("If-None-Match", Etag); var response = await httpClient.SendAsync(request); if (response.Headers.Contains("Etag")) { Etag = response.Headers.GetValues("Etag").First(); } if (response.StatusCode == System.Net.HttpStatusCode.OK) { var result = JsonConvert.DeserializeObject<GitResult>(await response.Content.ReadAsStringAsync()); StarCount = result.StarCount; } await signalRMessages.AddAsync( new SignalRMessage { Target = "newMessage", Arguments = new[] { $"Current star count of https://github.com/Azure/azure-signalr is: {StarCount}" } }); } private class GitResult { [JsonRequired] [JsonProperty("stargazers_count")] public string StarCount { get; set; } } } }
Function.cs中的 程式 代碼有三個函式:
GetHomePage
用來取得網站作為用戶端。Negotiate
用戶端會使用 來取得存取令牌。Broadcast
會定期呼叫 以從 GitHub 取得星號計數,然後將訊息廣播給所有用戶端。
此範例的用戶端介面是網頁。 我們從檔案 content/index.html 讀取 HTML 內容,以使用
GetHomePage
函式轉譯網頁。 現在,讓我們使用下列內容,content
在子目錄中建立此index.html:<html> <body> <h1>Azure SignalR Serverless Sample</h1> <div id="messages"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.7/signalr.min.js"></script> <script> let messages = document.querySelector('#messages'); const apiBaseUrl = window.location.origin; const connection = new signalR.HubConnectionBuilder() .withUrl(apiBaseUrl + '/api') .configureLogging(signalR.LogLevel.Information) .build(); connection.on('newMessage', (message) => { document.getElementById("messages").innerHTML = message; }); connection.start() .catch(console.error); </script> </body> </html>
更新 您的
*.csproj
,使組建輸出資料夾中的內容頁面。<ItemGroup> <None Update="content/index.html"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>
Azure Functions 需要記憶體帳戶才能運作。 您可以安裝並執行 Azure 儲存體 模擬器。 或者 ,您可以使用下列命令來更新 設定以使用實際的記憶體帳戶:
func settings add AzureWebJobsStorage "<storage-connection-string>"
現在幾乎完成了。 最後一個步驟是將 SignalR Service 的 連接字串 設定為 Azure 函式設定。
確認 SignalR Service 實例已成功建立,方法是在入口網站頂端的搜尋方塊中搜尋其名稱。 選取該執行個體以開啟它。
選取 [金鑰] 以檢視 SignalR Service 實例的 連接字串。
複製主要 連接字串,然後執行下列命令:
func settings add AzureSignalRConnectionString "<signalr-connection-string>"
在本機執行 Azure 函式:
func start
在 Azure 函式在本機執行之後,請開啟
http://localhost:7071/api/index
,您可以看到目前的星號計數。 如果您在 GitHub 中以星號或取消星號,您就會每隔幾秒鐘重新整理一次星號計數。
清除資源
如果您不打算繼續使用此應用程式,請使用下列步驟刪除本快速入門所建立的所有資源,因此不會產生任何費用:
在 Azure 入口網站中選取最左側的 [資源群組],然後選取您所建立的資源群組。 或者,您可以使用搜尋方塊依其名稱尋找資源群組。
在開啟的視窗中,選取資源群組,然後按兩下 [ 刪除資源群組]。
在新視窗中輸入要刪除之資源群組的名稱,然後按一下 [刪除]。
下一步
在本快速入門中,您已在本機建置並執行即時無伺服器應用程式。 接下來,深入瞭解用戶端與 Azure Functions 與 Azure SignalR Service 之間的雙向通訊。