【问题标题】:Why is SignalR hanging on second instance of localhost?为什么 SignalR 挂在 localhost 的第二个实例上?
【发布时间】:2016-01-08 18:59:30
【问题描述】:

我在 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();
    });

我的理论是,当我停止调试来自集线器的 SignalR 连接时,我已经打开的集线器在我第二次调试时从未关闭,并且 IIS 服务器无法处理许多连接?我不知道。我在github上找到了这个:

https://github.com/SignalR/SignalR/issues/3493 但没有人参与这些问题,最后一个版本已经发布了 1 年。

有没有办法在停止调试或 Global.Asax 上的 Application_Start() 等特定事件后停止从集线器创建的连接?因为如果我每次编写一些代码时都必须使用 signalR,我将不得不关闭并重新打开项目。我不知道这个问题是否会影响生产服务器。

【问题讨论】:

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


    【解决方案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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-20
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多