Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR hub scalability issue

We have a SignalR hub called StatusUpdateHub. This hub is updated by a .NET client called HubClient. This client will be (in production) called about 1000 times per second by multiple users for different transactions. Here is the client code:

public static class HubClient
{
    private static readonly string statusUpdateUrl = ConfigurationManager.AppSettings["StatusUpdateUrl"];
    private static readonly HubConnection connection = new HubConnection(statusUpdateUrl);
    private static readonly IHubProxy hub = connection.CreateProxy("StatusUpdateHub");

    internal static void UpdateBrowser(long transactionId)
    {
        connection.Start().ContinueWith(task => hub.Invoke("UpdateTransactionStatus", transactionId)).ContinueWith(task =>
        {
            if (task.IsFaulted && task.Exception != null)
            {
                // log error
            }
        });
    }
}

When this code is called with 100 concurrent users it is working fine but when we increase the number of concurrent users to 250 then we are seeing the following error:

Unexpected error in UpdateBrowser: System.InvalidOperationException: The connection has not been established. at SignalR.Client.Connection.SignalR.Client.IConnection.Send[T](String data) at SignalR.Client.Hubs.HubProxy.Invoke[T](String method, Object[] args) at SignalR.Client.Hubs.HubProxy.Invoke(String method, Object[] args) at Application.Services.HubClient.<>c_DisplayClass2.b_0(Task task1) in c:\Build\Work\Application\Services\HubClient.cs:line 20
at System.Threading.Tasks.Task`1.InvokeFuture(Object futureAsObj)
at System.Threading.Tasks.Task.Execute()

Let us know how we can make the code more scalable?

like image 663
Achinth Gurkhi Avatar asked Jul 25 '12 09:07

Achinth Gurkhi


People also ask

Is SignalR scalable?

A SignalR app can scale out based on the number of messages sent, while the Azure SignalR Service scales to handle any number of connections.

How many connections can SignalR handle?

In the default mode, the app server creates five server connections with Azure SignalR Service. The app server uses the Azure SignalR Service SDK by default. In the following performance test results, server connections are increased to 15 (or more for broadcasting and sending a message to a big group).

How long does a SignalR connection last?

The default keepalive timeout period is currently 20 seconds. If your client code tries to call a Hub method while SignalR is in reconnecting mode, SignalR will try to send the command. Most of the time, such attempts will fail, but in some circumstances they might succeed.

Does SignalR need SSL?

If your SignalR application transmits sensitive information between the client and server, use SSL for the transport.


2 Answers

If that's the method being called 1000 times per second, you shouldn't be calling connection.Start() every single time.

Open the connection only once, then just invoke methods on it.

Edit, what I mean is, at the very least, make your code do something like this:

internal static void UpdateBrowser(long transactionId)
{
    lock (connection) 
    {
        if (connection.State == ConnectionState.Disconnected){
            connection.Start().Wait();
        }
    }
    hub.Invoke("UpdateTransactionStatus", transactionId).ContinueWith(task =>
    {
        if (task.IsFaulted && task.Exception != null)
        {
            // log error
        }
    });
}
like image 189
andreialecu Avatar answered Sep 27 '22 17:09

andreialecu


By default .NET allows 2 concurrent connections outgoing from client apps and 10 from ASP.NET apps. If you want to increase this number then set the http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx to a bigger number. See if that helps.

like image 30
davidfowl Avatar answered Sep 27 '22 18:09

davidfowl