Skip to content

Commit 5e6860c

Browse files
Improve SignalR Nginx settings (dotnet#19983)
1 parent bd63aa0 commit 5e6860c

File tree

2 files changed

+77
-6
lines changed

2 files changed

+77
-6
lines changed

aspnetcore/host-and-deploy/linux-nginx.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ server {
145145
}
146146
```
147147

148-
If the app is a Blazor Server app that relies on SignalR WebSockets, see <xref:blazor/host-and-deploy/server#linux-with-nginx> for information on how to set the `Connection` header.
148+
If the app is a SignalR or Blazor Server app see <xref:signalr/scale#linux-with-nginx> and <xref:blazor/host-and-deploy/server#linux-with-nginx> respectively for more information.
149149

150150
When no `server_name` matches, Nginx uses the default server. If no default server is defined, the first server in the configuration file is the default server. As a best practice, add a specific default server which returns a status code of 444 in your configuration file. A default server configuration example is:
151151

aspnetcore/signalr/scale.md

+76-5
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,85 @@ The preceding conditions make it likely to hit the 10 connection limit on a clie
104104

105105
## Linux with Nginx
106106

107-
Set the proxy's `Connection` and `Upgrade` headers to the following for SignalR WebSockets:
107+
The following contains the minimum required settings to enable WebSockets, ServerSentEvents, and LongPolling for SignalR:
108108

109109
```nginx
110-
proxy_set_header Upgrade $http_upgrade;
111-
proxy_set_header Connection $connection_upgrade;
110+
http {
111+
map $http_connection $connection_upgrade {
112+
"~*Upgrade" $http_connection;
113+
default keep-alive;
114+
}
115+
116+
server {
117+
listen 80;
118+
server_name example.com *.example.com;
119+
120+
# Configure the SignalR Endpoint
121+
location /hubroute {
122+
# App server url
123+
proxy_pass http://localhost:5000;
124+
125+
# Configuration for WebSockets
126+
proxy_set_header Upgrade $http_upgrade;
127+
proxy_set_header Connection $connection_upgrade;
128+
proxy_cache off;
129+
130+
# Configuration for ServerSentEvents
131+
proxy_buffering off;
132+
133+
# Configuration for LongPolling or if your KeepAliveInterval is longer than 60 seconds
134+
proxy_read_timeout 100s;
135+
136+
proxy_set_header Host $host;
137+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
138+
proxy_set_header X-Forwarded-Proto $scheme;
139+
}
140+
}
141+
}
112142
```
113143

114-
For more information, see [NGINX as a WebSocket Proxy](https://www.nginx.com/blog/websocket-nginx/).
144+
When multiple backend servers are used, sticky sessions must be added to prevent SignalR connections from switching servers when connecting. There are multiple ways to add sticky sessions in Nginx. Two approaches are shown below depending on what you have available.
145+
146+
The following is added in addition to the previous configuration. In the following examples, `backend` is the name of the group of servers.
147+
148+
With [Nginx Open Source](https://nginx.org/en/), use `ip_hash` to route connections to a server based on the client's IP address:
149+
150+
```nginx
151+
http {
152+
upstream backend {
153+
# App server 1
154+
server http://localhost:5000;
155+
# App server 2
156+
server http://localhost:5002;
157+
158+
ip_hash;
159+
}
160+
}
161+
```
162+
163+
With [Nginx Plus](https://www.nginx.com/products/nginx), use `sticky` to add a cookie to requests and pin the user's requests to a server:
164+
165+
```nginx
166+
http {
167+
upstream backend {
168+
# App server 1
169+
server http://localhost:5000;
170+
# App server 2
171+
server http://localhost:5002;
172+
173+
sticky cookie srv_id expires=max domain=.example.com path=/ httponly;
174+
}
175+
}
176+
```
177+
178+
Finally, change `proxy_pass http://localhost:5000` in the `server` section to `proxy_pass http://backend`.
179+
180+
For more information on WebSockets over Nginx, see [NGINX as a WebSocket Proxy](https://www.nginx.com/blog/websocket-nginx).
181+
182+
For more information on load balancing and sticky sessions, see [NGINX load balancing](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/).
183+
184+
For more information about ASP.NET Core with Nginx see the following article:
185+
* <xref:host-and-deploy/linux-nginx>
115186

116187
## Third-party SignalR backplane providers
117188

@@ -123,4 +194,4 @@ For more information, see [NGINX as a WebSocket Proxy](https://www.nginx.com/blo
123194
For more information, see the following resources:
124195

125196
* [Azure SignalR Service documentation](/azure/azure-signalr/signalr-overview)
126-
* [Set up a Redis backplane](xref:signalr/redis-backplane)
197+
* [Set up a Redis backplane](xref:signalr/redis-backplane)

0 commit comments

Comments
 (0)