SignalR集线器可扩展性问题

时间:2012-07-25 09:37:24

标签: .net signalr signalr-hub

我们有一个名为StatusUpdateHub的SignalR中心。此集线器由名为HubClient的.NET客户端更新。对于不同的交易,该客户端(在生产中)被多个用户每秒调用大约1000次。这是客户端代码:

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
            }
        });
    }
}

当使用100个并发用户调用此代码时它工作正常,但是当我们将并发用户数增加到250时,我们看到以下错误:

  

UpdateBrowser中出现意外错误:System.InvalidOperationException:   连接尚未建立。在   SignalR.Client.Connection.SignalR.Client.IConnection.Send [T](字符串   SignalR.Client.Hubs.HubProxy.Invoke [T](String方法,   SignalR.Client.Hubs.HubProxy.Invoke(String。中的Object [] args)   方法,Object [] args)at   Application.Services.HubClient<> C_ DisplayClass2.b _0(任务   task1)在c:\ Build \ Work \ Application \ Services \ HubClient.cs中:第20行   在System.Threading.Tasks.Task`1.InvokeFuture(Object futureAsObj)
  在System.Threading.Tasks.Task.Execute()

让我们知道如何使代码更具可扩展性?

2 个答案:

答案 0 :(得分:10)

如果这个方法每秒被调用1000次,那么你不应该每次都调用connection.Start()

只打开一次连接,然后只调用它上面的方法。

编辑,我的意思是,至少,让您的代码执行以下操作:

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
        }
    });
}

答案 1 :(得分:5)

默认情况下,.NET允许从客户端应用程序传出2个并发连接,从ASP.NET应用程如果要增加此数字,请将http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx设置为更大的数字。看看是否有帮助。