2012-07-25 67 views
7

我们有一个名为StatusUpdateHub的SignalR集线器。该集线器由名为HubClient的.NET客户端进行更新。这个客户将会(在生产中)被多个用户每秒钟约1000次地进行不同的交易。下面是客户端代码:SignalR集线器可扩展性问题

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然后,我们看到下面的错误数量:

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()

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

+0

你有没有任何机会限制服务器上的同时连接? – Stilgar 2012-07-25 10:22:52

+0

您是否还在整个运行过程中监视内存消耗?你是。我很想知道,随着连接/断开连接的用户数量的增加,您看到的趋势是什么。我在我们的应用程序中看到了一些未释放的内存,并且怀疑它是由于SignalR还是其他原因。 – ElHaix 2012-07-25 12:32:58

+0

@Stilgar我们没有设置任何限制。我应该在machine.config中更改什么设置? – 2012-07-25 14:08:21

回答

9

如果这种方法每秒被调用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 
     } 
    }); 
}