如何在 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.");
}
}
}
在 .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.");
}
}
}