Skip to content

Commit a817547

Browse files
Merge pull request #298029 from kevinguo-ed/afd
Azure SignalR with Azure Front Door guide
2 parents 2ae79dc + 3566b53 commit a817547

File tree

6 files changed

+255
-0
lines changed

6 files changed

+255
-0
lines changed
149 KB
Loading
20.5 KB
Loading
202 KB
Loading
117 KB
Loading
137 KB
Loading
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
---
2+
title: How to use SignalR Service with Azure Front Door
3+
description: This article provides information about using Azure SignalR Service with Azure Front Door.
4+
author: kevinguo-ed
5+
ms.author: kevinguo
6+
ms.date: 04/10/2025
7+
ms.service: azure-signalr-service
8+
ms.topic: how-to
9+
---
10+
11+
# How to use Azure SignalR Service with Azure Front Door
12+
13+
Azure Front Door is a modern cloud-native application delivery network (ADN) that provides dynamic site acceleration, global load balancing, TLS termination, and application layer security. It operates at the HTTP/HTTPS layer (Layer 7) and acts as the entry point for web applications—routing and optimizing traffic based on attributes such as URL paths, latency, and health status of backends.
14+
15+
A key benefit of Azure Front Door is its native support for WebSocket and WebSocket Secure (WSS) connections. This support enables real-time, bi-directional communication between clients and backend services without requiring any special configuration.
16+
17+
In this guide, we demonstrate how to use Azure Front Door with Azure SignalR Service to front-end your real-time applications. By routing traffic through Front Door, you can:
18+
19+
- Apply WebSocket support with global reach and edge acceleration,
20+
- Apply centralized security policies, such as WAF rules and rate limiting,
21+
- Reduce public exposure of your backend services.
22+
23+
As shown in the diagram, you configure Azure Front Door to route WebSocket traffic to your SignalR-powered application backend. This setup ensures that your real-time functionality benefits from low-latency, scalable, and secure traffic handling through Azure’s global edge network.
24+
25+
## Set up and configure Azure Front Door
26+
27+
### Create an Azure SignalR Service resource
28+
29+
Follow [the article](./signalr-quickstart-azure-signalr-service-arm-template.md) and create a SignalR Service resource
30+
31+
### Create an Azure Front Door resource
32+
33+
On the [Azure portal](https://portal.azure.com/), search for **Front Door** and **Create**.
34+
35+
:::image type="content" source="./media/signalr-howto-work-with-azure-front-door/create-front-door.jpg" alt-text="Screenshot of creating an Azure Front Door resource.":::
36+
37+
38+
### Quick test
39+
Conduct quick tests to verify that SignalR endpoint is healthy and Azure Front Door resource is correctly configured.
40+
41+
Send a request to `<your-SignalR-resource-endpoint>/client` and it should return _400_ with error message _'hub' query parameter is required._ This message means that the request arrived at SignalR Service and the service performed validation as expected.
42+
```bash
43+
curl -v <your-SignalR-resource-endpoint>/client
44+
```
45+
Returns
46+
```
47+
< HTTP/1.1 400 Bad Request
48+
< ...
49+
<
50+
'hub' query parameter is required.
51+
```
52+
Send a request to the same health endpoint of Azure SignalR through Azure Front Door `http://<the-hostname-of-your-Azure-Front-Door-resource>/client`. Go to the Overview tab of the created Azure Front Door resource, and locate the endpoint hostname.
53+
54+
:::image type="content" source="./media/signalr-howto-work-with-azure-front-door/afd-hostname.jpg" alt-text="Screenshot of the the hostname of Azure Front Door resource":::
55+
56+
```bash
57+
curl -I http://<the-hostname-of-your-Azure-Front-Door-resource>/client
58+
```
59+
It should also return _400_ with error message _'hub' query parameter is required._ This message confirms that the request successfully went through Azure Front Door to SignalR Service.
60+
61+
```
62+
< HTTP/1.1 400 Bad Request
63+
< ...
64+
<
65+
'hub' query parameter is required.
66+
```
67+
68+
### Run a SignalR sample app through Azure Front Door
69+
70+
Now that we can verify that the traffic can reach SignalR Service through Azure Front Door. Next, we use a barebone sample app to demonstrate Azure Front Door's ability to route WebSocket traffic without configuration. We take a step-by-step approach so that you can follow along, if needed.
71+
72+
#### Create the project
73+
```bash
74+
mkdir afd-demo
75+
cd afd-demo
76+
77+
touch afd-demo.csproj
78+
```
79+
80+
Paste in the content to the `afd-demo.csproj` file. This project uses only the "Microsoft.Azure.SignalR" package.
81+
```json
82+
<Project Sdk="Microsoft.NET.Sdk.Web">
83+
<PropertyGroup>
84+
<TargetFramework>net7.0</TargetFramework>
85+
<Nullable>enable</Nullable>
86+
<ImplicitUsings>enable</ImplicitUsings>
87+
<RootNamespace>afd_demo</RootNamespace>
88+
</PropertyGroup>
89+
<ItemGroup>
90+
<PackageReference Include="Microsoft.Azure.SignalR" Version="1.30.2" />
91+
</ItemGroup>
92+
</Project>
93+
```
94+
95+
#### Configure app settings
96+
Create an `appsettings.json` file and paste in the content. The values will be referenced in the `Program.cs` file, which we create in the next step.
97+
```bash
98+
touch appsettings.json
99+
```
100+
101+
[!INCLUDE [Connection string security comment](includes/signalr-connection-string-security-comment.md)]
102+
103+
```json
104+
{
105+
"Azure": {
106+
"SignalR": {
107+
"ConnectionString": "<the-connection-string-of-your-Azure-SignalR-resource>"
108+
},
109+
"AFD": {
110+
"Endpoint": "<the-endpoint-of-your-Azure-Front-Door-resource>"
111+
}
112+
}
113+
}
114+
```
115+
116+
#### Create `Program.cs` file
117+
```bash
118+
touch Program.cs
119+
```
120+
121+
Paste in the code to the `Program.cs` file. The web app defines a SignalR hub and serves `index.html` at the web root.
122+
```csharp
123+
using Microsoft.Azure.SignalR;
124+
var builder = WebApplication.CreateBuilder(args);
125+
126+
// Reads in the configuration from `appsettings.json`
127+
var azureSignalRConnectionString = builder.Configuration["Azure:SignalR:ConnectionString"];
128+
var afdEndpoint = builder.Configuration["Azure:AFD:Endpoint"];
129+
130+
builder.Services.AddSignalR().AddAzureSignalR(o =>
131+
{
132+
o.Endpoints = new Microsoft.Azure.SignalR.ServiceEndpoint[1]
133+
{
134+
new Microsoft.Azure.SignalR.ServiceEndpoint(azureSignalRConnectionString)
135+
{
136+
// Instructs SignalR server to return a `ClientEndpoint` to SignalR clients, with which they establish a connection. In our case, it's the endpoint of the Azure Front Door resource you just created.
137+
ClientEndpoint = new Uri(afdEndpoint),
138+
}
139+
};
140+
});
141+
142+
var app = builder.Build();
143+
app.UseStaticFiles();
144+
145+
app.UseRouting();
146+
147+
app.MapHub<DemoHub>("/demohub");
148+
149+
app.MapGet("/", async context =>
150+
{
151+
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "index.html");
152+
context.Response.ContentType = "text/html";
153+
await context.Response.SendFileAsync(path);
154+
});
155+
156+
app.Run();
157+
```
158+
159+
#### Define a SignalR hub
160+
```bash
161+
mkdir hubs && cd hubs
162+
touch demohubs.cs
163+
```
164+
165+
Paste in the code to the `demohubs.cs` file. For simplicity, the hub exposes only `BroadcastMessage` method to SignalR client, which broadcasts the received message to all connected SignalR clients.
166+
```csharp
167+
using Microsoft.AspNetCore.SignalR;
168+
169+
public class DemoHub : Hub
170+
{
171+
public Task BroadcastMessage(string message) =>
172+
Clients.All.SendAsync("broadcastMessage", message);
173+
}
174+
```
175+
176+
#### Define Web UI
177+
Make sure you're at the root of the project folder.
178+
```bash
179+
mkdir wwwroot && cd wwwroot
180+
touch index.html
181+
```
182+
183+
Paste in the code to `index.html`. The user interface consists of a `<textarea>` to receive text input from user and a `<button>` to send the user input through a SignalR connection. Since we defined the SignalR server's behavior to broadcast received messages, you see the same message logged to the browser console.
184+
```html
185+
<!DOCTYPE html>
186+
<html>
187+
188+
<head>
189+
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
190+
<meta name="viewport" content="width=device-width">
191+
<meta http-equiv="Pragma" content="no-cache" />
192+
<meta http-equiv="Expires" content="0" />
193+
<title>Azure SignalR with Azure Front Door as the reverse proxy</title>
194+
</head>
195+
196+
<body>
197+
<div>
198+
<textarea id="message" style="display: block; width: 100%; padding: 5px 10px; max-width: 400px; margin-bottom: 8px;"
199+
placeholder="Your message..."></textarea>
200+
<button id="btn-send" disabled>Send</button>
201+
</div>
202+
203+
<!--Reference the SignalR library. -->
204+
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>
205+
206+
<script type="module">
207+
document.addEventListener("DOMContentLoaded", async function () {
208+
const connection = new signalR.HubConnectionBuilder()
209+
.withUrl("/demohub")
210+
.build();
211+
212+
connection.on("broadcastMessage", (msg) => {
213+
console.log(msg)
214+
})
215+
await connection.start();
216+
document.getElementById("btn-send").removeAttribute("disabled")
217+
218+
document.getElementById("btn-send").addEventListener("click", () => {
219+
const message = document.getElementById("message").value
220+
if (message !== "") {
221+
connection.send("broadcastMessage", message)
222+
document.getElementById("message").value = ""
223+
} else {
224+
alert("Message body is empty. Please enter message.")
225+
}
226+
})
227+
})
228+
</script>
229+
</body>
230+
231+
</html>
232+
```
233+
234+
#### Run the app and verify the flow of message through Azure Front Door
235+
That is all the code to the sample. Let's run the app.
236+
237+
```bash
238+
dotnet restore
239+
dotnet run
240+
```
241+
242+
Open http://localhost:5129 from the browser and use `F12` keyboard shortcut to open developer tools. Head to the network panel, you can see that the WebSocket connection is indeed established with Azure Front Door.
243+
244+
:::image type="content" source="./media/signalr-howto-work-with-azure-front-door/network-panel-afd.jpg" alt-text="Screenshot of the running app establishing a WebSocket connection with Azure Front Door.":::
245+
246+
Try to type something in the text box and hit the send button. You see the message is logged to browser console as expected.
247+
248+
:::image type="content" source="./media/signalr-howto-work-with-azure-front-door/console-log.jpg" alt-text="Screenshot of the received message in browser's console log.":::
249+
250+
You can also inspect the flow of messages in the network panel.
251+
252+
:::image type="content" source="./media/signalr-howto-work-with-azure-front-door/network-panel-flow-of-messages.jpg" alt-text="Screenshot of flow of messages in the network panel.":::
253+
254+
255+

0 commit comments

Comments
 (0)