2014-05-18 106 views
1

每当我的应用程序被重置时,signalR会断开连接但不会重新连接。SignalR断开连接并且不会重新连接

我有一个长时间运行的服务器任务,在每个任务完成时向客户端发送更新。

​​

上述代码时停止应用程序被复位发送更新(ⅰ可以模拟通过触摸的web.config这个问题)。

我想重新连接到客户端的方式。目前用户必须重新加载页面以便再次获取更新。

这里是我的枢纽定义

public class ForceHub : Hub 
{ 
    public void MessageSent(string text) 
    { 
     GetContext().Clients.All.sent(text); 
    } 

    public void UpdateStatus(string msg) 
    { 
     GetContext().Clients.All.status(msg); 
    } 

    IHubContext GetContext() 
    { 
     return GlobalHost.ConnectionManager.GetHubContext<ForceHub>(); 
    } 
    public override Task OnConnected() 
    { 
     try { 
      IoC.Resolve<ILogger>().Info("SignalR Connected -----------"); 
     }catch (Exception){} 

     return base.OnConnected(); 
    } 

    public override Task OnDisconnected() 
    { 
     try { 
      IoC.Resolve<ILogger>().Info("SignalR Disconnected -----------"); 
     } 
     catch (Exception) { } 
     return base.OnDisconnected(); 
    } 

    public override Task OnReconnected() 
    { 
     try { 
      IoC.Resolve<ILogger>().Info("SignalR Re-Connected -----------"); 
     } 
     catch (Exception) { } 
     return base.OnReconnected(); 
    } 
} 

我可以看到连接重新接活动启动后触发,但是触摸web.config文件之后,我看不到任何这些事件触发。

我试图在客户端上赶上这一点,但这一事件不会tirggered:

$.connection.hub.disconnected(function() { 
    console.error('signalR disconnected, retrying connection'); 
    logError('Signal lost.'); 
    setTimeout(function() { connection.start(); }, 1000); 
}); 

更新

我也钩入状态改变事件,该事件被触发,但再下面的连接尝试不起作用。

 $.connection.hub.stateChanged(function (state) { 
      console.debug('signalR state changed', state); 
      if (state.newState == 1) { 
       console.debug('restarting'); 
       setTimeout(function() { $.connection.hub.start(); }, 1000); 
      } 
     }); 

此事件被触发两次:newState是2,然后1

+0

它看起来像一个有趣的案例,我想摄制它,但我不能。我没有尝试长时间运行的任务,但有一个简单的附加页面,其代码在用GET命中时向所有客户端发送消息。这模拟了一个“带外”工作,即使在应用程序重置后,它也能正常工作,客户端得到正常通知。我会说SignalR不会失去连接(这就是为什么你没有看到事件)......也许问题在别的地方? – Wasp

+0

@Wasp是否尝试修改web.config? –

+0

当然,我是这样做的请求之间我的“工作”页面 – Wasp

回答

0

我可能有一个线索...触摸的Web.config产生程序池回收,这意味着一个新的工作进程为新的请求创建,而现有的过程将持续一段时间,直到剩余的请求结束或达到超时。在超时期限内未结束的请求被终止。

Signalr客户端重新连接到新的过程,而长期运行的任务是在旧的进程中运行,所以当在长时间运行的任务,你做

GlobalHost.ConnectionManager.GetHubContext<ForceHub>(); 

你实际上得到的“老”枢纽而基准客户端连接到“新”集线器。 这就是为什么由Wasp执行测试的原因:他发出了一个新的请求,在新创建的工作进程中处理的信号中心上发布。

您可以尝试配置信号背板(https://www.asp.net/signalr/overview/performance/scaleout-in-signalr),使用Sql Server(https://www.asp.net/signalr/overview/performance/scaleout-with-sql-server)配置它非常容易。背板应该能够连接两个工作进程,并希望您能够在客户端获得通知。

如果出现这种问题,即使没有底板,由新请求生成的通知也可以正常工作。请注意,背板的真正目的是扩展信号发生器,即在它们之间连接一个WebServers场。

另外请记住,在IIS内部运行长时间运行的任务非常难以实现,因为IIS会定期执行appPool回收操作并对请求执行超时限制。我建议你阅读以下文章:http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx “如果你认为自己可以写一个背景任务,那很可能你会错误的。我不是在质疑你的技能,我只是说它很微妙。另外,你为什么要这样吗?”

希望这有助于

+0

这听起来正确:)多年来没有触及该代码。我同意IIS中长时间运行的任务并不理想。我能够将执行时间降低到1-30分钟,这个时间仍然很长,但在过去几年中一直可以管理。谢谢! –

相关问题