What is your product version? 11.0.0
What is your product type (Angular or MVC)? Angular
What is product framework type (.net framework or .net core)? .NET 6
Hi, We are using microsoft signalR service for real time communication, but the service wont work if we scale out the app service instance from one to two instance, while using single instacne it is working fine. for exp : Ideally the SignalR connection is established with the instance1. But the request API went to the other app service instance2. The instance2 won't be able to send this message because this specific server connection is not associated with it.
Please help us to resolve that issue we are created the ticket for the same in microsoft and ans was "With this, root cause of the issue is identified, and this issue is expected behavior as per your architecture/application design"
Thanks
17 Answer(s)
-
0
Hi @shedspotter
You can solve this in two ways;
- You can use Redis for scaling the SignalR, see https://docs.microsoft.com/en-us/aspnet/core/signalr/redis-backplane?view=aspnetcore-6.0
- Or, you can use Azure SignalR Service if you are hosting on Azure, see https://docs.microsoft.com/en-us/azure/azure-signalr/signalr-quickstart-dotnet-core
-
0
Hi @ismcagdas We already using the Azure SignalR Service service but still we are getting the same issue
-
0
Hi,
Could you share how did you configure your Startup.cs for Azure SignalR service ?
-
0
Hi @ismcagdas I have configured like this
#if DEBUG services.AddSignalR(); #else services.AddSignalR(options => { options.EnableDetailedErrors = true; }) .AddAzureSignalR(options => options.Endpoints = new ServiceEndpoint[] { new ServiceEndpoint(_appConfiguration["SignalR:PrimaryConnectionString"], EndpointType.Primary, "primary--signalrservice.service.signalr.net"), new ServiceEndpoint(_appConfiguration["SignalR:SecondaryConnectionString"], EndpointType.Secondary, "secondary-signalrservice.service.signalr.net"), });
#endif
-
0
Hi,
Thanks, this seems fine. Is it possible that your app is running in DEBUG mode on your production ? Cound you be sure that
AddAzureSignalR
is executed ?Thanks,
-
0
Hi, our production application is running in release mode and I am 100% sure that AddAzureSignalR is executed
-
0
Hi, I have created a POC project to verify the singalR issue with multiple instace in azure and the POC is working fine with microsft signalR but in asp net zero application it is not working correctly.If you need I can share the POC project
-
0
Hi @shedspotter
Is it possible to share teh problematic project via email ?
Thanks,
-
0
Hi, sorry I am unable to share the whole project it would be great if we can schedule a call
-
0
Hi @shedspotter
Sure, please send an email to [email protected] and we can arrange the meeting.
-
0
Hi @ismcagdas , I have send you the mail in same email thread which is already running
-
0
Hi @shedspotter
Thanks, we got the email and will reply back soon.
-
0
Even though you are using Azure SignalR, the app is still responsible for storing who is connected, so when it has to send a message to a particular user, you know how to send it. This is done with IOnlineClientManager. The default version of this uses memory Cache to store who is connected which in a scaled environment doesn't work. You have to change this to be some shared cache . I've seen a thread in here recently where someone used Azure storage for this, we use Redis for this. I copied code from someone else a long while ago that still works today. Would be happy to share the code with either of you. Sorry, I'm in the middle of a big deployment and I noticed this message and new without looking that this was probably the problem. I emailed my code to info@ and they can reply to those that need it.
It would be a nice addition to the codebase.
-
0
Hi @ismcagdas Please let me know when we are scheduling the call the as we are not hearing any repsonses from your side on this issue as well as the other performance related issue
Thanks
-
0
Hi @ismcagdas, Could you please me to saving the client connection Id in DB
Thanks
-
0
Hi @shedspotter
We can continue via email for this topic. When you use Redis, it will store the connection. So it is similar to saving the connection to DB.
-
0
EDIT: I posted to soon. The code below works for sending messages to clients but does not help with tracking a count of clients or if a user is online.
I recently encountered the same problem and decided to use the Groups feature in SignalR. This blog article recommended that and per my limited testing, it works well https://consultwithgriff.com/signalr-connection-ids/
In the OnConnectedAsync, I add the connection to a group for the tenant and also to a group for the user. I would recommend that ANZ adopt this approach because I believe it would work with either a single server or a scaled out system.
I am willing to share more code if you wish.
Here's an example of how I extended the AbpCommonHub
` public class AbpCommonHubExtended : AbpCommonHub { private readonly IOnlineClientManager _onlineClientManager;
public AbpCommonHubExtended( IOnlineClientManager onlineClientManager, IOnlineClientInfoProvider clientInfoProvider) : base(onlineClientManager, clientInfoProvider) { _onlineClientManager = onlineClientManager; } public override async Task OnConnectedAsync() { await base.OnConnectedAsync(); var client = _onlineClientManager.GetByConnectionIdOrNull(Context.ConnectionId); await Groups.AddToGroupAsync( client.ConnectionId, GetGroupName_AllClientsForTenant( client.TenantId.GetValueOrDefault())); await Groups.AddToGroupAsync( client.ConnectionId, GetGroupName_AllClientsForUser( client.TenantId.GetValueOrDefault(), client.UserId.GetValueOrDefault())); } public static string GetGroupName_AllClientsForTenant(int tenantId) { return $"t_{tenantId}"; } public static string GetGroupName_AllClientsForUser(int tenantId, long userId) { return $"t_{tenantId}_u_{userId}"; } }
`