关于asp.net mvc:signalR跟踪已连接的用户

signalR tracking connected users

我需要检查特定用户是否仍处于连接状态。

我有以下HashSet可以跟踪用户:

1
2
3
4
public static class UserHandler
{
    public static HashSet<string> ConnectedIds = new HashSet<string>();
}

如此断开:

1
2
3
4
5
6
7
8
9
    public override Task OnDisconnected()
    {
        UserHandler.ConnectedIds.Remove(this.Context.ConnectionId);
        if (UserHandler.ConnectedIds.Count == 0)
        {
               // STOP TASK -> SET CANCELLATION
        }
        return base.OnDisconnected();
    }

并在连接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    public override Task OnConnected()
    {
        Logger.Log.file.Info("[TaskActionStatus HUB => OnConnected] Start");

        UserHandler.ConnectedIds.Add(this.Context.ConnectionId);

        // start task only if at least one listener
        if (UserHandler.ConnectedIds.Count < 2)
        {
            // START A TASK -> (WHILE LOOP THAT GETS DATA FROM DB EVERY 2 SEC)
        }

        return base.OnConnected();
    }

现在,当用户只是关闭他/她的浏览器窗口时,就会出现问题。我无法知道他/她是否断开连接。

因此,基于这里的一些问题,我会打电话给每个客户并得到答复。我不确定该怎么做。

我想我会这样:

1
2
3
4
5
6
7
8
public static void CheckConnectedUsers()
{
    var context = GlobalHost.ConnectionManager.GetHubContext<TaskActionStatus>();
    foreach (var connection in UserHandler.ConnectedIds)
    {
        context.Clients.Client(connection).verifyConnected("online?");
    }
}

但是我如何从客户那里得到回应?

编辑:
执行的步骤:

我需要连接的确切用户数,因为如果连接了至少一个用户,则需要启动任务。我想确保所有连接的用户<2(启动任务)仅运行1个任务。假设情况如下:2个用户查看使用signalR的页面。 HashSet现在包含2个ID,并且一个任务正在运行。一个关闭他/她的浏览器,几秒钟后,另一个刷新他/她的。现在,第一个(关闭他/她的浏览器的人没有执行OnDisconnected方法,因此HashSet仍然有他/她的ConnectionId,而"刷新"的那个人则执行OnDisonnected,然后是OnConnected,后者将他的connectionId添加到HashSet中。由于HashSet中只有1个ConnectionId并启动了一个任务,因此HashSet包含2个(不再保持旧连接,并且刚刚刷新了他/她的浏览器),并且该任务再也没有开始。

谢谢


使用SignalR 1.0,即使用户关闭窗口,OnDisconnected也应始终触发(服务器重新启动时例外)。

OnDisconnected可能不会立即触发,因为如果客户端未"中止"连接,则认为该连接是"不干净的",因为客户端有可能尝试重新连接(并且如果您重新连接,则根据SignalR的说明未断开连接) 语义)。

默认情况下,服务器调用OnDisconnected可能需要大约30秒钟来进行"不干净的"断开连接。 可以通过GlobalHost.Configuration.DisconnectTimeout重新配置。


我刚刚遇到过同样的情况。 不总是触发onDisconnect。 我的解决方案是不定期轮询用户,以查看他们是否仍处于连接状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Public Sub checkconnections()
    For Each s In users
        Clients.User(s).areYouThere()
    Next
    users = New List(Of String)
    System.Threading.Thread.Sleep(5000)
    checkconnections()
End Sub
Public Sub imHere()
    Dim id = GetClientId()
    If Not users.Contains(id) Then
        users.Add(id)
    End If
    Clients.All.sendCount(count)
End Sub

因此集线器每5秒钟发送一次到用户列表中的所有客户端,然后清除列表。

如果客户端收到" areYouThere"消息,则以" imHere"答复,然后将其添加到列表中。

希望这可以帮助。