我们有一个名为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()
让我们知道如何使代码更具可扩展性?
答案 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设置为更大的数字。看看是否有帮助。