首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SignalR断开连接,不重新连接

SignalR断开连接,不重新连接
EN

Stack Overflow用户
提问于 2014-05-18 22:01:01
回答 1查看 4K关注 0票数 1

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

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

代码语言:javascript
运行
复制
// inside action executed on every completion of a task
var h = new ForceHub();
h.MessageSent(email);

上面的代码在应用程序被重置时停止发送更新(我可以通过触摸web.config来模拟这个问题)。

我想要一种重新连接到客户的方式。目前,用户必须重新加载页面才能再次获得更新。

这是我的集线器定义

代码语言:javascript
运行
复制
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之后,我没有看到任何这些事件被触发。

我试着在客户机上捕捉到这一点,但是这个事件并没有被破坏:

代码语言:javascript
运行
复制
$.connection.hub.disconnected(function () {
    console.error('signalR disconnected, retrying connection');
    logError('Signal lost.');
    setTimeout(function () { connection.start(); }, 1000);
});

更新

我还连接到了State事件,它确实会被触发,但是下面的重连接尝试不起作用。

代码语言:javascript
运行
复制
        $.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。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-12 11:42:28

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

当长时间运行的任务在旧进程中运行时,Signalr客户端重新连接到新进程,因此,在长时间运行的任务上,您可以这样做。

代码语言:javascript
运行
复制
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:“如果你认为你可以自己写一个背景任务,你很可能会弄错。我不是在指责你的技巧,我只是说这很微妙。另外,你为什么要这么做呢?“

希望这能有所帮助

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23727309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档