Search code examples
asp.net-coresignalrsignalr-hub

High number of SignalR requests compared to rest of application


We have an ASP.NET MVC .NET 7 app running on Azure App Services. The app supports around 50-60 concurrent users in a typical day. Users will stay logged in for hours, as this is a line-of-business application.

The application is scaled out to two instances and we use Redis as the backplane for SignalR.

In Application Insights, we're seeing a huge number of requests for SignalR compared with the rest of our app. For example, in a 10 minute period today, we saw over 21,000 requests compared with just 4-500 requests for normal MVC actions.

Is this normal? Seems very wrong to us.

I should add that we're not even very SignalR heavy, we just use it for Toasts and a few basic UI updates.

See screenshot:

enter image description here

Excerpt from Startup.cs:

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapControllers();
    endpoints.MapHub<AppGlobalHub>("hubs/global");
});

Extracts from AppGlobalHub.cs:

public interface IAppGlobalHub
{
    Task AdminAlert(string message);
}

[Authorize]
public AppGlobalHub : Hub<IAppGlobalHub>
{
    public async Task AdminAlert(string message)
    {
        await Clients.Group(GROUP_ADMINISTRATORS).AdminAlert(message);
    }
}

Example of hub controller DI:

public class ExampleController : Controller
{
    private readonly IHubContext<AppGlobalHub, IAppGlobalHub> _appGlobalHub;

    public ExampleController(IHubContext<AppGlobalHub, IAppGlobalHub> appGlobalHub)
    {
        _appGlobalHub = appGlobalHub
    }
}

Sending signals via controller:

[HttpGet]
public async Task<IActionResult> Example()
{
    await _appGlobalHub.Clients.All.AdminAlert("hello world");

    ...
}

Example of usage in front end (typescript + Razor):

 this.connection = new signalR.HubConnectionBuilder()
     .withUrl("/hubs/global")
     .withAutomaticReconnect()
     .build();
 
 ...

 this.connection.on('AdminMessage', (msg) => {
   console.log(msg);
 }); 

 ...

 this.connection.invoke("AdminMessage", "hello world");


If there's an implementation error here, please let me know. Always learning.

However, if the above behaviour is normal (i.e. many requests), please explain. We may have 50-60 users, and they may have a couple of tabs open, so I supposed you might argue there are, say, 150 connections at any one time. But the number of requests still seems ridiculous.

If this is not normal, what can be causing this level? What's the best way to diagnose/trace this traffic to see where it's coming from?

Update 2023-05-05

BrennanConroy on GitHub said that the inbalance between requests to /global and /global/negotiate was due to not having websockets enabled. We've fixed that issue now. But does that explain the high number of requests?


Solution

  • Please see this github issue: https://github.com/dotnet/aspnetcore/issues/48080#event-9176618832

    Brennan Conroy pointed out that it appeared websockets wasn't activated on the app service. He was right.

    As soon as we switched that on, the requests plummeted and are now in line with the rest of the app.