【问题标题】:SignalR: Detecting Alive Connection in C# clientsSignalR:检测 C# 客户端中的活动连接
【发布时间】:2014-09-12 17:32:42
【问题描述】:

我目前正在使用 SignalR (2.1) 集线器开发应用程序。

我有 1 个 WPF 客户端,另一个是 WCF 客户端。 一切正常,因为它们完美地传递了消息。

我现在面临的唯一问题是,当应用程序由于自动重启、WCF 服务器关闭等原因而关闭时,我注意到 OnDisconnected 根本没有被触发。超时是默认的 30 秒。即使经过 1 天(我试过),它也不会被调用。但是,超时适用于 Web 客户端。

它仅在我调用 hub.connection.stop() 时有效。

然而,当客户端是浏览器时,Ondisconnected 方法效果很好。

所以想问一下Signal R Hub端有没有办法可以检查客户端是否还在连接或者已经掉线(比如ping)?

【问题讨论】:

  • 1) 您应该在 github 上为 .net signalr 客户端提交一个错误(或者他们可能已经有错误?)。 2)您可以轻松实现自己的ping机制,在客户端和集线器之间来回发送机制
  • 好吧,我通读并注意到这段文字说“如果您的 Web 服务器停止工作或应用程序重新启动,则不会调用 OnDisconnected 方法。因此,您的数据存储库可能会有记录不再有效的连接 ID。”在asp.net/signalr/overview/signalr-20/hubs-api/…。因此,我知道他们知道这件事。但是,我的问题是,SignalR 集线器是否有任何内置方法可以通知连接是否已断开,而不是我每隔几秒钟 ping 一次。

标签: c# signalr


【解决方案1】:

在 SignalR 2.1.0 中,有一个 new overload to OnDisconnected 接受一个布尔值,指示客户端是否正常断开连接。 2.1.0 release notes 的“重大更改”部分解释了此更改背后的原因。

您的新 OnDisconnected 方法可能如下所示:

public override Task OnDisconnected(bool stopCalled)
{
    if (stopCalled)
    {
        // We know that Stop() was called on the client,
        // and the connection shut down gracefully.
    }
    else
    {
        // This server hasn't heard from the client in the last ~35 seconds.
        // If SignalR is behind a load balancer with scaleout configured, 
        // the client may still be connected to another SignalR server.
    }

    return base.OnDisconnected(stopCalled);
}

不采用 bool 的旧 OnDisconnected 方法不会为非正常断开调用调用,因此如果您使用该事件,则可以解释您所看到的问题。

在 2.1.0 之前,(唯一的)不带参数的 OnDisconnected 方法被调用用于优雅的 非优雅的断开连接。由于这种行为变化导致several reported issues,旧的OnDisconnected 过载is being removed in SignalR's upcoming 2.1.1 release

这将导致使用 SignalR 的旧 OnDisconnected 方法的应用程序在针对 SignalR 2.1.1 构建时无法编译。虽然这并不理想,但它有望让开发人员意识到这一重大变化,以便他们有机会在部署之前适当地修改他们的应用程序。

【讨论】:

  • 完美。我刚刚测试过,是的。这是在开火。非常感谢楼主!
  • halter73,谢谢。我发现了一个小错误。如果我在下一行使用“virtual”,OnDisconnected 方法不会触发: public virtual Task OnDisconnected(bool stopCalled) 我使用“override”而不是“virtual”并且它可以工作。
  • 谢谢。我修正了我的答案。
  • 警告:我发现如果我没有在 .Net 客户端中的连接上显式调用 Dispose(或用于使用似乎对这种连接不实用的块),此事件永远不会开火。
  • @dudeNumber4 在 .NET 客户端上,Connection.Stop 和 Connection.Dispose 是等价的。
【解决方案2】:

我发现如果我强制服务器关闭连接,我的客户端将无法重新连接。 (我会收到一个 WSSockets 错误)

所以,对我来说,解决方法是:

con = new HubConnection(_url);
con.Error += (exception) => Error(exception);
con.Start();

然后,在 Error 方法中,通过再次调用上述代码尝试重新连接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-09
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多