我在MVC应用程序中测试SignalR时遇到问题。下面发布的代码一切正常,但是我发现如果我的localhost应用程序出错(某些逻辑失败并引发异常)我必须停止重新编译,修复问题,然后重新构建项目再次调试Web应用程序,但在第二次我调试页面永远不会加载时,它只是在选项卡上显示旋转加载图标,并且永远不会完成加载页面。所以我需要关闭项目并重新打开它。这是代码:
public ActionResult Save()
{
//Some code and then calling the hub
var context = GlobalHost.ConnectionManager.GetHubContext<UpdatesHub>();
context.Clients.All.updateUsers();
return RedirectToAction("Index", "Home");
}
我的中心就像这样:
[HubName("updateHub")]
public class UpdatesHub : Hub
{
public void UpdatedUsers()
{
Clients.All.updateUsers();
}
}
和javascript:
$(function () {
var hub = $.connection.updateHub;
//THe method called from MVC for real time update table
hub.client.updateUsers= function () {
$.ajax({
url: "@Url.Action("GetUsers", "Home")",
type: "GET",
cache: false,
success: function (result) {
$("#UserList").html(result);
}
});
}
$.connection.hub.start();
});
我的理论是,当我第二次调试并且IIS服务器无法处理多个连接时,当我停止调试来自集线器的SignalR连接时,我从未关闭过。我不知道。我在github上找到了这个:
https://github.com/SignalR/SignalR/issues/3493但没有人参加这些问题,最后一个版本是1岁。
有没有办法在停止调试或Global.Asax上的Application_Start()等特定事件后停止从集线器创建的连接?因为如果每次编写代码时都必须使用signalR,我必须关闭并重新打开项目。我不知道这个问题是否会影响生产服务器。
答案 0 :(得分:1)
搜索后我在这里找到了解决方案。这个解决方案对我有用
MVC5 hangs on MapSignalR when reconnecting after AppPool cycles
根据这个https://github.com/SignalR/SignalR/pull/3609,这个问题会有一些正确的解决办法。
我创建了性能计数器的虚拟实现,并使用它而不是标准的性能计数器。
// Global.asmx
var tempCounterManager = new TempPerformanceCounterManager();
GlobalHost.DependencyResolver.Register(typeof (IPerformanceCounterManager), () => tempCounterManager);
[....]
// Helper Class
public class TempPerformanceCounterManager : IPerformanceCounterManager
{
private readonly static PropertyInfo[] _counterProperties = GetCounterPropertyInfo();
private readonly static IPerformanceCounter _noOpCounter = new NoOpPerformanceCounter();
public TempPerformanceCounterManager()
{
foreach (var property in _counterProperties)
{
property.SetValue(this, new NoOpPerformanceCounter(), null);
}
}
public void Initialize(string instanceName, CancellationToken hostShutdownToken)
{
}
public IPerformanceCounter LoadCounter(string categoryName, string counterName, string instanceName, bool isReadOnly)
{
return _noOpCounter;
}
internal static PropertyInfo[] GetCounterPropertyInfo()
{
return typeof(TempPerformanceCounterManager)
.GetProperties()
.Where(p => p.PropertyType == typeof(IPerformanceCounter))
.ToArray();
}
public IPerformanceCounter ConnectionsConnected { get; set; }
public IPerformanceCounter ConnectionsReconnected { get; set; }
public IPerformanceCounter ConnectionsDisconnected { get; set; }
public IPerformanceCounter ConnectionsCurrentForeverFrame { get; private set; }
public IPerformanceCounter ConnectionsCurrentLongPolling { get; private set; }
public IPerformanceCounter ConnectionsCurrentServerSentEvents { get; private set; }
public IPerformanceCounter ConnectionsCurrentWebSockets { get; private set; }
public IPerformanceCounter ConnectionsCurrent { get; private set; }
public IPerformanceCounter ConnectionMessagesReceivedTotal { get; private set; }
public IPerformanceCounter ConnectionMessagesSentTotal { get; private set; }
public IPerformanceCounter ConnectionMessagesReceivedPerSec { get; private set; }
public IPerformanceCounter ConnectionMessagesSentPerSec { get; private set; }
public IPerformanceCounter MessageBusMessagesReceivedTotal { get; private set; }
public IPerformanceCounter MessageBusMessagesReceivedPerSec { get; private set; }
public IPerformanceCounter ScaleoutMessageBusMessagesReceivedPerSec { get; private set; }
public IPerformanceCounter MessageBusMessagesPublishedTotal { get; private set; }
public IPerformanceCounter MessageBusMessagesPublishedPerSec { get; private set; }
public IPerformanceCounter MessageBusSubscribersCurrent { get; private set; }
public IPerformanceCounter MessageBusSubscribersTotal { get; private set; }
public IPerformanceCounter MessageBusSubscribersPerSec { get; private set; }
public IPerformanceCounter MessageBusAllocatedWorkers { get; private set; }
public IPerformanceCounter MessageBusBusyWorkers { get; private set; }
public IPerformanceCounter MessageBusTopicsCurrent { get; private set; }
public IPerformanceCounter ErrorsAllTotal { get; private set; }
public IPerformanceCounter ErrorsAllPerSec { get; private set; }
public IPerformanceCounter ErrorsHubResolutionTotal { get; private set; }
public IPerformanceCounter ErrorsHubResolutionPerSec { get; private set; }
public IPerformanceCounter ErrorsHubInvocationTotal { get; private set; }
public IPerformanceCounter ErrorsHubInvocationPerSec { get; private set; }
public IPerformanceCounter ErrorsTransportTotal { get; private set; }
public IPerformanceCounter ErrorsTransportPerSec { get; private set; }
public IPerformanceCounter ScaleoutStreamCountTotal { get; private set; }
public IPerformanceCounter ScaleoutStreamCountOpen { get; private set; }
public IPerformanceCounter ScaleoutStreamCountBuffering { get; private set; }
public IPerformanceCounter ScaleoutErrorsTotal { get; private set; }
public IPerformanceCounter ScaleoutErrorsPerSec { get; private set; }
public IPerformanceCounter ScaleoutSendQueueLength { get; private set; }
}
internal class NoOpPerformanceCounter : IPerformanceCounter
{
public string CounterName
{
get
{
return GetType().Name;
}
}
public long Decrement()
{
return 0;
}
public long Increment()
{
return 0;
}
public long IncrementBy(long value)
{
return 0;
}
public long RawValue
{
get { return 0; }
set { }
}
public void Close()
{
}
public void RemoveInstance()
{
}
public CounterSample NextSample()
{
return CounterSample.Empty;
}
}