signalrasp.net-core-signalrazure-signalrsignalr-backplane

Azure SignalR Service: No active connection for user


In the live trace tool on the Azure portal, I consistently get the message that the user message was not received because there’s no active connection for user XXX

I'm using a custom IUserIdProvider in my ASP.NET Core app. When I use the default, in-memory functionality of SignalR, this works like a charm. However, with Azure SignalR Service, there seems to be a mismatch between connections and User IDs.

A connection is made, but this doesn’t seem to find its way back to Azure SignalR service, because the other User IDs shown in the trace cannot be traced back to our code. The result of that is that no message ever arrives in the users’ browsers. In the screenshot attached, the user IDs in the first two lines seem to be auto-generated by Azure SignalR Service, while the third row indicates a user id in our app. Hence the warning message that there aren't any active connections for that user.

enter image description here

Not much fancy is going on in our app in terms of SignalR config:

  services
  .AddSignalR()
  .AddAzureSignalR(signalRConnString);
  
  services.AddSingleton<IUserIdProvider, UserIdProvider>();

UserIdProvider's code combines two claims from the connection's user:

public class UserIdProvider : IUserIdProvider
{
  public virtual string GetUserId(HubConnectionContext connection) 
    => connection.User?.FindFirst("CLAIM1")?.Value!
       + "_T_"
       + connection.User?.FindFirst("CLAIM2")?.Value!;
}

The hub itself is pretty bland, there's not much going on. Except when broadcasting from the server to a subselection of users, who are retrieved from the cache/database based on several business rules. I simply fetch a list of users that should receive this message, after which I just invoke:

await HubContext.Clients.User(x.UserId).SendAsync(...);

As mentioned before, without Azure SignalR, this works perfectly.

Perhaps this could be the problem, but I'm actually invoking SignalR through IHubContext<T>. There have been similar topics on the subject that suggest something like this:

ServiceManager serviceManager = new ServiceManagerBuilder().WithOptions(option => { option.ConnectionString = signalRConnString; }).BuildServiceManager();
ServiceHubContext hubContext = serviceManager.CreateHubContextAsync(HubNames.PlanningHub, CancellationToken.None).Result;
services.Add(new ServiceDescriptor(typeof(IHubContext<Hub>), hubContext));

Is there any extra config that must be provided to Azure SignalR Service to be able to use the same IUserIdProvider instance?


Solution

  • Everything works fine when using Asp.Net Core SignalR, but there are problems when using Azure SignalR.

    At this time, we first need to configure Azure SignlaR correctly, and then check how the connection is created in the front-end code. The first thing we need to check is the SkipNegotation option. We need to disable or delete it to connect and use azure signalr normally. Official doc: Configure additional options

    enter image description here