如何在 asp.net 核心 SignalR 中迭代用户?

How to iterate over users in asp.net core SignalR?

在 .net 核心上的 SignalR 应用程序中,我有一段类似于以下的工作代码:

public Task SendPrivateMessage(string user, string message)
{
    var sender = Context.User.Claims.FirstOrDefault(cl => cl.Type == "username")?.Value;
    return Clients.User(user)
                  .SendAsync("ReceiveMessage", $"Message from {sender}: {message}");
}

这会将一条消息从当前连接的用户发送到指定的用户。

现在我想向每个 连接的用户发送一条单独的消息;类似于以下概念:

public Task UpdateMessageStatus()
{
    foreach(client in Clients.Users)
    {
         var nrOfMessages = GetMessageCount();
         client.SendAsync($"You have {nrOfMessages} messages.");
    }
}

我怎样才能做到这一点;即我如何遍历连接的用户,并向他们每个人发送单独的消息?

编辑/澄清

如前所述,我需要向每个连接的用户发送 个人(即专门的)消息,因此使用 Clients.All 不是一个选项,因为那只能是用于向所有连接的用户发送相同的消息。

我最终做了类似于 Mark C. 在接受的答案中发布的内容。

您可以使用 Clients.All 向所有客户发送消息。

return Clients.All.SendAsync("ReceiveMessage", $"Message from {sender}: {message}");

如果您不想使用提供给您的 Clients.All API,您可以保留已连接用户的本地缓存并将其用作已连接用户列表。

像这样:

static HashSet<string> CurrentConnections = new HashSet<string>();

    public override Task OnConnected()
    {
        var id = Context.ConnectionId;
        CurrentConnections.Add(id);

        return base.OnConnected();
    }

    public Task SendAllClientsMessage()
    {
        foreach (var activeConnection in GetAllActiveConnections())
        {
            Clients.Client(activeConnection).SendMessageAsync("Hi");
        }
    }

    public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
    {
        var connection = CurrentConnections.FirstOrDefault(x => x == Context.ConnectionId);

        if (connection != null)
        {
            CurrentConnections.Remove(connection);
        }

        return base.OnDisconnected(stopCalled);
    }


    //return list of all active connections
    public List<string> GetAllActiveConnections()
    {
        return CurrentConnections.ToList();
    }

我最终创建了一个管理我自己的已连接用户列表,类似于

稍微扩展一下,这将允许我做类似以下概念的事情:

public async Task CheckAllMessages()
{
    foreach (var user in ConnectedUsers)
    {
       var nr = GetNrOfMessagesForUser(user);
       if(nr > 0)
       {
           await Clients.User(user)
                        .SendAsync("ReceiveMessage", 
                                   $"User ({user}) has {nr} new messages waiting.");
       }
    }
}