signalR跟踪连接的用户

时间:2013-03-04 13:52:51

标签: asp.net-mvc signalr signalr-hub

我需要检查特定用户是否仍然连接。

我有以下用于跟踪用户的HashSet:

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

因此断开连接:

    public override Task OnDisconnected()
    {
        UserHandler.ConnectedIds.Remove(this.Context.ConnectionId);
        if (UserHandler.ConnectedIds.Count == 0)
        {
               // STOP TASK -> SET CANCELLATION
        }
        return base.OnDisconnected();
    }

并在Connected上:

    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();
    }

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

所以基于一些问题here,我会打电话给每个客户并得到回复。我不知道怎么做。

我想我会这样:

public static void CheckConnectedUsers()
{
    var context = GlobalHost.ConnectionManager.GetHubContext<TaskActionStatus>();
    foreach (var connection in UserHandler.ConnectedIds)
    {
        context.Clients.Client(connection).verifyConnected("online?");
    }
}

但我如何从客户端获得回复?

编辑: 执行的步骤:

我需要连接的确切用户数,因为如果至少连接了一个用户,我需要启动一项任务。我想确保所有连接用户只运行1个任务&lt; 2(开始任务)。假设这样的情况:2个用户查看使用signalR的页面。 HashSet现在包含2个ID,并且正在运行任务。一个关闭他/她的浏览器,几秒钟后,另一个刷新他/她的浏览器。现在,第一个(关闭他/她的浏览器的那个没有执行OnDisconnected方法,所以HashSet仍然有他/她的ConnectionId,而“刷新”的那个确实执行OnDisonnected,然后OnConnected将connectionId添加到HashSet。所以相反在HashSet中只有一个ConnectionId并启动一个任务,HashSet包含2个(旧的 - 不再连接,只是刷新他/她的浏览器的那个),并且任务再也没有开始。

感谢

2 个答案:

答案 0 :(得分:6)

使用SignalR 1.0,OnDisconnected应该始终触发,即使用户关闭其窗口(如果服务器重新启动,则会出现例外情况)。

OnDisconnected可能不会立即触发,因为如果客户端没有“中止”该连接,则会被视为“不干净”,因为客户可能会尝试重新连接(如果您重新连接,则可以根据SignalR的语义断开连接。)

默认情况下,服务器调用OnDisconnected进行“不清洁”断开连接大约需要30秒。这可以通过GlobalHost.Configuration.DisconnectTimeout重新配置。

答案 1 :(得分:0)

我刚遇到同样的情况。 onDisconnect并不总是被触发。我的解决方案是偶尔轮询用户以查看他们是否仍然连接。

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秒发送一次用户列表中的所有客户端,然后清除列表。

如果客户收到“你是否有”这样的话。它回复的消息&#39; imHere&#39;然后将其添加到列表中。

希望这有帮助。