为什么SignalR挂在localhost的第二个实例上?

时间:2016-01-08 18:59:31

标签: c# asp.net-mvc signalr signalr-hub

我在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,我必须关闭并重新打开项目。我不知道这个问题是否会影响生产服务器。

1 个答案:

答案 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;
    }
}