Skip to content

Commit c38007c

Browse files
committed
Update SignalR serverless multiple endpoint doc
1 parent f5e4552 commit c38007c

File tree

3 files changed

+395
-15
lines changed

3 files changed

+395
-15
lines changed

articles/azure-signalr/signalr-concept-disaster-recovery.md

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ ms.devlang: csharp
88
ms.custom: devx-track-csharp
99
ms.date: 03/01/2019
1010
ms.author: lianwei
11+
zone_pivot_groups: azure-signalr-service-mode
1112
---
1213
# Resiliency and disaster recovery in Azure SignalR Service
1314

@@ -48,10 +49,9 @@ Multiple SignalR service instances are supported on both app servers and Azure F
4849

4950
Once you have SignalR service and app servers/Azure Functions created in each region, you can configure your app servers/Azure Functions to connect to all SignalR service instances.
5051

51-
### Configure on app servers
52-
There are two ways you can do it:
52+
:::zone pivot="default-mode"
5353

54-
#### Through config
54+
### Through config
5555

5656
You should already know how to set SignalR service connection string through environment variables/app settings/web.cofig, in a config entry named `Azure:SignalR:ConnectionString`.
5757
If you have multiple endpoints, you can set them in multiple config entries, each in the following format:
@@ -63,7 +63,7 @@ Azure:SignalR:ConnectionString:<name>:<role>
6363
In the ConnectionString, `<name>` is the name of the endpoint and `<role>` is its role (primary or secondary).
6464
Name is optional but it's useful if you want to further customize the routing behavior among multiple endpoints.
6565

66-
#### Through code
66+
### Through code
6767

6868
If you prefer to store the connection strings somewhere else, you can also read them in your code and use them as parameters when calling `AddAzureSignalR()` (in ASP.NET Core) or `MapAzureSignalR()` (in ASP.NET).
6969

@@ -94,9 +94,86 @@ You can configure multiple primary or secondary instances. If there are multiple
9494

9595
1. If there is at least one primary instance online, return a random primary online instance.
9696
2. If all primary instances are down, return a random secondary online instance.
97+
:::zone-end
98+
:::zone pivot="serverless-mode"
9799

98-
### Configure on Azure Functions
99-
See [this article](https://github.com/Azure/azure-functions-signalrservice-extension/blob/dev/docs/sharding.md#configuration-method).
100+
### For SignalR Functions extensions
101+
102+
To enable multiple SignalR Service instances, you should:
103+
104+
1. Use `Persistent` transport type.
105+
106+
The default transport type is `Transient` mode. You should add the following entry to your `local.settings.json` file or the application setting on Azure.
107+
108+
```json
109+
{
110+
"AzureSignalRServiceTransportType":"Persistent"
111+
}
112+
```
113+
>Notes for switching from `Transient` mode to `Persistent` mode on **Azure Functions runtime V3 and above** :
114+
>
115+
> Under `Transient` mode, `Newtonsoft.Json` library is used to serialize arguments of hub methods, however, under `Persistent` mode, `System.Text.Json` library is used as default on Azure Functions runtime V3 or above. `System.Text.Json` has some key differences in default behavior with `Newtonsoft.Json`. If you want to use `Newtonsoft.Json` under `Persistent` mode, you can add a configuration item: `"Azure:SignalR:HubProtocol":"NewtonsoftJson"` in `local.settings.json` file or `Azure__SignalR__HubProtocol=NewtonsoftJson` on Azure portal.
116+
117+
118+
2. Configure multiple SignalR Service endpoints entries in your configuration.
119+
120+
We use a [`ServiceEndpoint`](https://github.com/Azure/azure-signalr/blob/dev/src/Microsoft.Azure.SignalR.Common/Endpoints/ServiceEndpoint.cs) object to represent a SignalR Service instance. You can define an service endpoint with its `<EndpointName>` and `<EndpointType>` in the entry key, and the connection string in the entry value. The keys are in the following format :
121+
122+
```
123+
Azure:SignalR:Endpoints:<EndpointName>:<EndpointType>
124+
```
125+
126+
`<EndpointType>` is optional and defaults to `primary`. See samples below:
127+
128+
```json
129+
{
130+
"Azure:SignalR:Endpoints:EastUs":"<ConnectionString>",
131+
132+
"Azure:SignalR:Endpoints:EastUs2:Secondary":"<ConnectionString>",
133+
134+
"Azure:SignalR:Endpoints:WestUs:Primary":"<ConnectionString>"
135+
}
136+
```
137+
138+
> * When you configure Azure SignalR endpoints in the App Service on Azure portal, don't forget to replace `":"` with `"__"`, the double underscore in the keys. For reasons, see [Environment variables](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-5.0#environment-variables).
139+
>
140+
> * Connection string configured with the key `{ConnectionStringSetting}` (defaults to "AzureSignalRConnectionString") is also recognized as a primary service endpoint with empty name. But this configuration style is not recommended for multiple endpoints.
141+
142+
### For [Management SDK](./signalr-howto-use-management-sdk.md)
143+
#### Add multiple endpoints from config
144+
145+
Configure with key `Azure:SignalR:Endpoints` for SignalR Service connection string. The key should be in the format `Azure:SignalR:Endpoints:{Name}:{EndpointType}`, where `Name` and `EndpointType` are properties of the `ServiceEndpoint` object, and are accessible from code.
146+
147+
You can add multiple instance connection strings using the following `dotnet` commands:
148+
149+
```cmd
150+
dotnet user-secrets set Azure:SignalR:Endpoints:east-region-a <ConnectionString1>
151+
dotnet user-secrets set Azure:SignalR:Endpoints:east-region-b:primary <ConnectionString2>
152+
dotnet user-secrets set Azure:SignalR:Endpoints:backup:secondary <ConnectionString3>
153+
```
154+
155+
#### Add multiple endpoints from code
156+
157+
A `ServiceEndpoint` class describes the properties of an Azure SignalR Service endpoint.
158+
You can configure multiple instance endpoints when using Azure SignalR Management SDK through:
159+
```cs
160+
var serviceManager = new ServiceManagerBuilder()
161+
.WithOptions(option =>
162+
{
163+
options.Endpoints = new ServiceEndpoint[]
164+
{
165+
// Note: this is just a demonstration of how to set options.Endpoints
166+
// Having ConnectionStrings explicitly set inside the code is not encouraged
167+
// You can fetch it from a safe place such as Azure KeyVault
168+
new ServiceEndpoint("<ConnectionString0>"),
169+
new ServiceEndpoint("<ConnectionString1>", type: EndpointType.Primary, name: "east-region-a"),
170+
new ServiceEndpoint("<ConnectionString2>", type: EndpointType.Primary, name: "east-region-b"),
171+
new ServiceEndpoint("<ConnectionString3>", type: EndpointType.Secondary, name: "backup"),
172+
};
173+
})
174+
.BuildServiceManager();
175+
```
176+
:::zone-end
100177

101178
## Failover sequence and best practice
102179

@@ -127,7 +204,7 @@ After all existing clients disconnect, your system will be back to normal (Fig.1
127204

128205
There are two main patterns for implementing a cross region high available architecture:
129206

130-
1. The first one is to have a pair of app server and SignalR service instance taking all online traffic, and have another pair as a backup (called active/passive, illustrated in Fig.1).
207+
1. The first one is to have a pair of app server and SignalR service instance taking all online traffic, and have another pair as a backup (called active/passive, illustrated in Fig.1).
131208
2. The other one is to have two (or more) pairs of app servers and SignalR service instances, each one taking part of the online traffic and serves as backup for other pairs (called active/active, similar to Fig.3).
132209

133210
SignalR service can support both patterns, the main difference is how you implement app servers.
@@ -143,7 +220,7 @@ You need to handle such cases at client side to make it transparent to your end
143220

144221
Follow the steps to trigger the failover:
145222
1. In the Networking tab for the primary resource in the portal, **disable** public network access. If the resource has private network enabled, use *access control rules* to deny all the traffic.
146-
2. **Restart** the primary resource.
223+
2. **Restart** the primary resource.
147224

148225
## Next steps
149226

0 commit comments

Comments
 (0)