每当我的应用程序被重置时,signalR会断开连接,但不会重新连接。
我有一个长时间运行的服务器任务,它在每个任务完成后向客户端发送更新。
// inside action executed on every completion of a task
var h = new ForceHub();
h.MessageSent(email);
上面的代码在应用程序被重置时停止发送更新(我可以通过触摸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之后,我没有看到任何这些事件被触发。
我试着在客户机上捕捉到这一点,但是这个事件并没有被破坏:
$.connection.hub.disconnected(function () {
console.error('signalR disconnected, retrying connection');
logError('Signal lost.');
setTimeout(function () { connection.start(); }, 1000);
});
更新
我还连接到了State事件,它确实会被触发,但是下面的重连接尝试不起作用。
$.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。
发布于 2017-01-12 11:42:28
我可能有线索..。触摸Web.config会产生一个appPool回收,这意味着将为新请求创建一个新的工作进程,而现有进程将持续一段时间,直到剩余的请求结束或到达超时为止。未在超时期间结束的请求将被终止。
当长时间运行的任务在旧进程中运行时,Signalr客户端重新连接到新进程,因此,在长时间运行的任务上,您可以这样做。
GlobalHost.ConnectionManager.GetHubContext<ForceHub>();
当客户端连接到“新”集线器时,您实际上得到了“旧”集线器的引用。这就是由Wasp预先准备的测试成功的原因:他提出了一个在新创建的工作进程中处理的signalr集线器上发布的新请求。
您可以尝试配置singalr背板(https://www.asp.net/signalr/overview/performance/scaleout-in-signalr),使用Server (https://www.asp.net/signalr/overview/performance/scaleout-with-sql-server)配置它非常容易。背板应该能够连接这两个工作进程,希望您能够在客户机上得到通知。
如果这是问题所在,即使没有背板,由新请求生成的通知也会正常工作。注意,背板的真正目的是扩展signalr,这是为了在它们之间连接一个WebServers场。
还请记住,在IIS中运行长期运行的任务是很难实现的,因为IIS执行常规的appPool回收,并且有执行请求的超时限制。我建议你阅读以下文章:http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx:“如果你认为你可以自己写一个背景任务,你很可能会弄错。我不是在指责你的技巧,我只是说这很微妙。另外,你为什么要这么做呢?“
希望这能有所帮助
https://stackoverflow.com/questions/23727309
复制相似问题