Skip to content

Commit 1557c16

Browse files
committed
Add c# isolated worker for quick start sample
1 parent 1875ddd commit 1557c16

File tree

1 file changed

+103
-9
lines changed

1 file changed

+103
-9
lines changed

articles/azure-signalr/signalr-quickstart-azure-functions-csharp.md

Lines changed: 103 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,26 @@ ms.service: signalr
66
ms.devlang: csharp
77
ms.topic: quickstart
88
ms.custom: devx-track-csharp, mode-other
9-
ms.date: 03/30/2022
9+
ms.date: 12/28/2022
1010
ms.author: lianwei
1111
---
1212

1313
# Quickstart: Create an app showing GitHub star count with Azure Functions and SignalR Service via C#
1414

1515
In this article, you'll learn how to use SignalR Service and Azure Functions to build a serverless application with C# to broadcast messages to clients.
1616

17+
# [In-process](#tab/in-process)
18+
1719
> [!NOTE]
1820
> You can get the code mentioned in this article from [GitHub](https://github.com/aspnet/AzureSignalR-samples/tree/main/samples/QuickStartServerless/csharp).
1921
22+
# [Isolated process](#tab/isolated-process)
23+
24+
> [!NOTE]
25+
> You can get the code mentioned in this article from [GitHub](https://github.com/aspnet/AzureSignalR-samples/tree/main/samples/QuickStartServerless/csharp-isolated).
26+
27+
---
28+
2029
## Prerequisites
2130

2231
The following prerequisites are needed for this quickstart:
@@ -37,6 +46,8 @@ You'll need the Azure Functions Core Tools for this step.
3746
1. Create an empty directory and change to the directory with the command line.
3847
1. Initialize a new project.
3948

49+
# [In-process](#tab/in-process)
50+
4051
```bash
4152
# Initialize a function project
4253
func init --worker-runtime dotnet
@@ -45,8 +56,22 @@ You'll need the Azure Functions Core Tools for this step.
4556
dotnet add package Microsoft.Azure.WebJobs.Extensions.SignalRService
4657
```
4758

59+
# [Isolated process](#tab/isolated-process)
60+
61+
```bash
62+
# Initialize a function project
63+
func init --worker-runtime dotnet-isolated
64+
65+
# Add extensions package references to the project
66+
dotnet add package Microsoft.Azure.WebJobs.Extensions.SignalRService
67+
dotnet add package Microsoft.Azure.WebJobs.Extensions.Http
68+
dotnet add package Microsoft.Azure.WebJobs.Extensions.Timer
69+
```
70+
4871
1. Using your code editor, create a new file with the name *Function.cs*. Add the following code to *Function.cs*:
4972

73+
# [In-process](#tab/in-process)
74+
5075
```csharp
5176
using System;
5277
using System.IO;
@@ -59,15 +84,15 @@ You'll need the Azure Functions Core Tools for this step.
5984
using Microsoft.Azure.WebJobs.Extensions.Http;
6085
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
6186
using Newtonsoft.Json;
62-
87+
6388
namespace CSharp
6489
{
6590
public static class Function
6691
{
6792
private static HttpClient httpClient = new HttpClient();
6893
private static string Etag = string.Empty;
6994
private static string StarCount = "0";
70-
95+
7196
[FunctionName("index")]
7297
public static IActionResult GetHomePage([HttpTrigger(AuthorizationLevel.Anonymous)]HttpRequest req, ExecutionContext context)
7398
{
@@ -78,15 +103,15 @@ You'll need the Azure Functions Core Tools for this step.
78103
ContentType = "text/html",
79104
};
80105
}
81-
106+
82107
[FunctionName("negotiate")]
83-
public static SignalRConnectionInfo Negotiate(
108+
public static SignalRConnectionInfo Negotiate(
84109
[HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req,
85110
[SignalRConnectionInfo(HubName = "serverless")] SignalRConnectionInfo connectionInfo)
86111
{
87112
return connectionInfo;
88113
}
89-
114+
90115
[FunctionName("broadcast")]
91116
public static async Task Broadcast([TimerTrigger("*/5 * * * * *")] TimerInfo myTimer,
92117
[SignalR(HubName = "serverless")] IAsyncCollector<SignalRMessage> signalRMessages)
@@ -104,15 +129,15 @@ You'll need the Azure Functions Core Tools for this step.
104129
var result = JsonConvert.DeserializeObject<GitResult>(await response.Content.ReadAsStringAsync());
105130
StarCount = result.StarCount;
106131
}
107-
132+
108133
await signalRMessages.AddAsync(
109134
new SignalRMessage
110135
{
111136
Target = "newMessage",
112137
Arguments = new[] { $"Current star count of https://github.com/Azure/azure-signalr is: {StarCount}" }
113138
});
114139
}
115-
140+
116141
private class GitResult
117142
{
118143
[JsonRequired]
@@ -123,6 +148,75 @@ You'll need the Azure Functions Core Tools for this step.
123148
}
124149
```
125150
151+
# [Isolated process](#tab/isolated-process)
152+
153+
```csharp
154+
using System.Net;
155+
using System.Net.Http.Json;
156+
using System.Text.Json.Serialization;
157+
using Microsoft.Azure.Functions.Worker;
158+
using Microsoft.Azure.Functions.Worker.Http;
159+
160+
namespace csharp_isolated;
161+
162+
public class Functions
163+
{
164+
private static readonly HttpClient HttpClient = new();
165+
private static string Etag = string.Empty;
166+
private static int StarCount = 0;
167+
168+
[Function("index")]
169+
public static HttpResponseData GetWebPage([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req)
170+
{
171+
var response = req.CreateResponse(HttpStatusCode.OK);
172+
response.WriteString(File.ReadAllText("content/index.html"));
173+
response.Headers.Add("Content-Type", "text/html");
174+
return response;
175+
}
176+
177+
[Function("negotiate")]
178+
public static HttpResponseData Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequestData req,
179+
[SignalRConnectionInfoInput(HubName = "serverless")] string connectionInfo)
180+
{
181+
var response = req.CreateResponse(HttpStatusCode.OK);
182+
response.Headers.Add("Content-Type", "application/json");
183+
response.WriteString(connectionInfo);
184+
return response;
185+
}
186+
187+
[Function("broadcast")]
188+
[SignalROutput(HubName = "serverless")]
189+
public static async Task<SignalRMessageAction> Broadcast([TimerTrigger("*/5 * * * * *")] TimerInfo timerInfo)
190+
{
191+
var request = new HttpRequestMessage(HttpMethod.Get, "https://api.github.com/repos/azure/azure-signalr");
192+
request.Headers.UserAgent.ParseAdd("Serverless");
193+
request.Headers.Add("If-None-Match", Etag);
194+
var response = await HttpClient.SendAsync(request);
195+
if (response.Headers.Contains("Etag"))
196+
{
197+
Etag = response.Headers.GetValues("Etag").First();
198+
}
199+
if (response.StatusCode == HttpStatusCode.OK)
200+
{
201+
var result = await response.Content.ReadFromJsonAsync<GitResult>();
202+
if (result != null)
203+
{
204+
StarCount = result.StarCount;
205+
}
206+
}
207+
return new SignalRMessageAction("newMessage", new object[] { $"Current star count of https://github.com/Azure/azure-signalr is: {StarCount}" });
208+
}
209+
210+
private class GitResult
211+
{
212+
[JsonPropertyName("stargazers_count")]
213+
public int StarCount { get; set; }
214+
}
215+
}
216+
```
217+
218+
---
219+
126220
The code in *Function.cs* has three functions:
127221
- `GetHomePage` is used to get a website as client.
128222
- `Negotiate` is used by the client to get an access token.
@@ -188,7 +282,7 @@ You'll need the Azure Functions Core Tools for this step.
188282
func start
189283
```
190284
191-
After the Azure function is running locally, open `http://localhost:7071/api/index` and you can see the current star count. If you star or unstar in the GitHub, you'll get a star count refreshing every few seconds.
285+
After the Azure function is running locally, open `http://localhost:7071/api/index`, and you can see the current star count. If you star or unstar in the GitHub, you'll get a star count refreshing every few seconds.
192286
193287
> [!NOTE]
194288
> SignalR binding needs Azure Storage, but you can use a local storage emulator when the function is running locally.

0 commit comments

Comments
 (0)