如何正确使用SignalR事件来保持连接活跃?

28

我正在使用SignalR、ASP.NET和C#开发一个实时的客户端/服务器应用程序。我正在使用本地主机和VS2013作为托管。

我的问题是:

  1. 为什么如果我关闭服务器,在Web客户端上会发生“重新连接”事件?

  2. 只有40多秒后,“断开连接”事件才会发生。如何缩短这个时间?

  3. 我需要客户端在启动时连接到服务器。只有当“重新连接”间隔时间达到固定间隔时,才应触发“重新连接”事件。如果“重新连接”间隔时间超过,客户端应该作为新客户端连接。如何实现这个目标?

最后,我想问 - 如何以正确的方式使用SignalR保持连接?

我正在使用以下代码:

C#

public override Task OnDisconnected()
{
clientList.RemoveAt(nIndex);
Console.WriteLine("Disconnected {0}\n", Context.ConnectionId);
return (base.OnDisconnected());
}

public override Task OnReconnected()
{
Console.WriteLine("Reconnected {0}\n", Context.ConnectionId);
return (base.OnReconnected());
}

JavaScript

$.connection.hub.reconnected(function () {
// Html encode display name and message.
var encodedName = $('<div />').text("heartbeat").html();
var now = new Date();

// Add the message to the page.
$('#discussion').append('Reconnected to server: ' + now + '</br>');
});

$.connection.hub.disconnected(function () {
// Html encode display name and message.
var encodedName = $('<div />').text("heartbeat").html();
var now = new Date();
// Add the message to the page.
$('#discussion').append('Disconnected from server: ' + now + '</br>');
});

连接后的输出:

message received from server : Fri Feb 21 2014 10:53:02

关闭服务器后的输出:

Reconnected to server: Fri Feb 21 2014 10:53:22 <-- Why, if i close server ???
Disconnected from server: Fri Feb 21 2014 10:53:53 <-- Why 40+ seconds after the server is closed ?
2个回答

32

1. 当我关闭服务器后,在Web客户端上会出现“重新连接”事件,只有在之后才会出现“断开连接”事件。为什么?

SignalR无法区分关闭服务器和重启服务器之间的差别。因此,当服务器关闭时,客户端将开始尝试重新连接,以防服务器实际上正在重新启动。

2. “断开连接”发生在未知“重新连接”的30秒后。如何缩短此时间?

可以通过DisconnectTimeout属性来修改这个30秒超时。

3. 我需要客户端在启动时连接到服务器。 “重新连接”应该只在固定间隔内发生。如果“重新连接”间隔时间已超过,则客户端应连接为新客户端。

您应该在断开事件后启动连接,最好在延迟一段时间后进行操作,以减少服务器负载(如果服务器正在重新启动)。

$.connection.hub.disconnected(function() {
    setTimeout(function() {
        $.connection.hub.start();
    }, 5000); // Re-start connection after 5 seconds
});

整篇理解和处理SignalR中的连接生命周期事件文章可能与您的问题相关。


但是,当您处于断开状态时,您不会失去客户端上所有已订阅的事件吗?您如何重新创建这些订阅(例如.On<T>(...)扩展)? - Killnine
1
只要您仍在使用原始的(Hub)连接对象,即使重新启动已断开的连接,订阅也应该继续工作。 - halter73
1
@halter73 我认为你需要重新订阅之前加入的群组。 - Shyamal Parikh
2
@ShyamalParikh 正确。如果您手动重新启动连接,则需要重新订阅组。我只是想指出,如果您使用Connnection对象,则不必再次通过.On<T>(...)配置回调。 - halter73
是否有任何事件可以在SignalR重新启动时触发?这样客户端就不需要在设置的超时时间内不断地ping以获取新连接了。 - Saravana

3
这种方法适用于您不想更改服务器配置的情况; JavaScript示例代码:
connection.serverTimeoutInMilliseconds = 1000 * 60 * 10; // for  10 minute

1
谢谢,@SyeedMasoudTayefi。这是哪个连接对象?是 $ .connection 还是连接代理 $ .connection.myHub.connection - Alex

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