SignalR:在C#客户端中检测活动连接

13

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

我有一个WPF客户端和另一个是WCF客户端。 在这两个客户端之间传递消息时一切都很好。

现在面临的唯一问题是,当应用程序出于自动重启、WCF服务器宕机等原因关闭时,我注意到OnDisconnected根本没有被触发。超时时间为默认的30秒。即使过了1天,它也从未被调用(我已经尝试过)。但是,Web客户端可以正常工作。

只有当我调用hub.connection.stop()时它才有效。

然而,当客户端是浏览器时,Ondisconnected方法非常有效。

因此,我想问Signal R Hub是否有办法检查客户端是否仍然连接或已经掉线(例如ping)?


1
  1. 你应该在 GitHub 上为 .NET SignalR 客户端提交一个 bug(或者他们已经有了一个 bug?)。
  2. 你可以轻松地实现自己的 ping 机制,来回发送机制在客户端和中心之间。
- Robert Levy
我浏览了一下,发现网站上有这样一段话:“如果您的Web服务器停止工作或应用程序重新启动,则不会调用OnDisconnected方法。因此,您的数据存储库可能会有连接ID的记录已不再有效。”,这是在http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections中提到的。因此,我知道他们知道这个问题。但是我的问题是,SignalR hub是否有任何内置方法可以注意到连接是否已断开,而不是我每隔几秒钟就进行一次ping操作。 - Kiong
2个回答

24
在SignalR 2.1.0中,有一个新的OnDisconnected重载,它接受一个布尔值,指示客户端是否正常断开连接。这个改变的原因在2.1.0版本说明的“Breaking Changes”部分有解释。
你的新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);
}

老版本的OnDisconnected方法没有bool参数,所以对于非正常断开连接的情况不会被调用。如果你正在使用这个事件,那么这可能解释了你所看到的问题。

在2.1.0之前,只有一个没有参数的OnDisconnected方法既可以处理正常断开连接也可以处理非正常断开连接。由于这种行为的变化导致了多个报告的问题,因此旧的OnDisconnected重载将在SignalR即将发布的2.1.1版本中被删除

当应用程序构建在SignalR 2.1.1上时,这将导致使用SignalR旧的OnDisconnected方法的应用程序无法编译。虽然这并不理想,但希望这能让开发人员意识到这个破坏性的变化,以便在部署应用程序之前适当地修改它们。


完美的。我刚刚测试了,是的。这正在运行。非常感谢您先生! - Kiong
halter73,谢谢。我发现了一个小错误。如果我在下一行使用“virtual”:public virtual Task OnDisconnected(bool stopCalled),则OnDisconnected方法不会触发。我改用“override”而不是“virtual”,它就可以工作了。 - Ainullin Damir
谢谢。我修正了我的答案。 - halter73
1
警告:我发现如果我在 .Net 客户端中没有显式调用 Dispose(或使用 using 块,但对于这样的连接似乎不实用),则此事件将永远不会触发。 - dudeNumber4
1
@dudeNumber4 在.NET客户端中,Connection.Stop和Connection.Dispose是等价的。 - halter73
@halter73 在OnDisconnected方法没有被触发时,我们可以使用connection.stop和connection.dispose。你能试试吗? - Khalid

0

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

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

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接