Skip to content

Commit 87dab80

Browse files
authored
Configure SignalR hub URL endpoint for loopback hub connections (#36769)
1 parent c24f144 commit 87dab80

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

aspnetcore/blazor/fundamentals/signalr.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,76 @@ protected override async Task OnInitializedAsync()
17991799

18001800
In the preceding code, `NavManager` is a <xref:Microsoft.AspNetCore.Components.NavigationManager>, and `AuthenticationStateProvider` is an <xref:Microsoft.AspNetCore.Components.Authorization.AuthenticationStateProvider> service instance ([`AuthenticationStateProvider` documentation](xref:blazor/security/authentication-state)).
18011801

1802+
## Configure the hub URL endpoint for a loopback connection
1803+
1804+
*This section only applies to server-side Blazor apps.*
1805+
1806+
If HTTP requests in a server-side Blazor app are failing to connect to itself when using <xref:Microsoft.AspNetCore.Components.NavigationManager.ToAbsoluteUri%2A?displayProperty=nameWithType>, you might have a load balancer or proxy that isn't expecting requests from the backend server. In this scenario, you can try to change the hub URL that the client is using to connect directly to the backend server.
1807+
1808+
The following example:
1809+
1810+
* Configures the hub URL using <xref:System.UriBuilder> and passes it to <xref:Microsoft.AspNetCore.SignalR.Client.HubConnectionBuilderHttpExtensions.WithUrl%2A>.
1811+
* Sets the URI based on the server's address (<xref:Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>) and machine name (<xref:System.Environment.MachineName%2A>).
1812+
1813+
```razor
1814+
@using System.Net
1815+
@using System.Net.Sockets
1816+
@using Microsoft.AspNetCore.Hosting.Server
1817+
@using Microsoft.AspNetCore.Hosting.Server.Features
1818+
@using Microsoft.AspNetCore.SignalR.Client
1819+
@inject IHostEnvironment Environment
1820+
@inject IServer Server
1821+
1822+
...
1823+
1824+
@code {
1825+
private HubConnection? hubConnection;
1826+
1827+
protected override async Task OnInitializedAsync()
1828+
{
1829+
var serverAddress = Server.Features
1830+
.Get<IServerAddressesFeature>()?
1831+
.Addresses
1832+
.FirstOrDefault(a => a.StartsWith("http://") || a.StartsWith("https://"));
1833+
1834+
if (serverAddress is null)
1835+
{
1836+
throw new InvalidOperationException("No server address available.");
1837+
}
1838+
1839+
var uri = new UriBuilder(serverAddress + "/chathub");
1840+
1841+
// If Kestrel is bound to a wildcard, substitute a real IP
1842+
if (uri.Host is "0.0.0.0" or "[::]" or "+" or "*")
1843+
{
1844+
var addresses = await Dns.GetHostAddressesAsync(
1845+
System.Environment.MachineName);
1846+
var ip = addresses.FirstOrDefault(a =>
1847+
a.AddressFamily == AddressFamily.InterNetwork
1848+
&& !IPAddress.IsLoopback(a));
1849+
1850+
if (ip is null)
1851+
{
1852+
throw new InvalidOperationException("No suitable IP address.");
1853+
}
1854+
1855+
uri.Host = ip.ToString();
1856+
}
1857+
1858+
hubConnection = new HubConnectionBuilder()
1859+
.WithUrl(uri.Uri)
1860+
.Build();
1861+
1862+
hubConnection.On<ChatMessage>("ReceiveMessage", (message) =>
1863+
{
1864+
...
1865+
});
1866+
1867+
await hubConnection.StartAsync();
1868+
}
1869+
}
1870+
```
1871+
18021872
## Additional server-side resources
18031873

18041874
* [Server-side host and deployment guidance: SignalR configuration](xref:blazor/host-and-deploy/server/index#signalr-configuration)

0 commit comments

Comments
 (0)