我有以下Hub片段与SignalR,Redis背板和单个服务器一起使用 .
public abstract class HubBase : Hub
{
private readonly static ConnectionMapping Connections = new ConnectionMapping();
public override Task OnConnected()
{
Connections.Add(Context.User.Identity.Name, Context.ConnectionId);
return base.OnConnected();
}
}
我将连接用户存储在静态变量中,因此我可以将connectionId映射到用户名,并且稍后可以向特定用户发送消息 .
我的问题是,是否会在SignalR场中的所有服务器上调用OnConnected函数?我测试了它,从它的外观来看,它只在客户端连接的服务器上调用 .
如果没有在所有服务器上调用它,那么处理这种情况的推荐方法是什么?
编辑:现在考虑这个我意识到我的示例代码可能有一个严重的缺陷 . 如果在另一台服务器上也调用了OnConnected方法,那么显然不会设置Context.User.Identity.Name,因为调用没有请求 . 我想解决这个问题的唯一方法就是使用组 .
1 回答
有一种方法可以做到这一点,但正如penderi所说,信号器是无状态的,所以无法保证特定用户仍然连接 . 我不确定Redis,但SQL服务器底板使用IMessageBus,并且它将所有消息存储在本地缓存中,如果用户断开连接,则IMessageBus进程将发送自用户断开连接后用户重新连接时已广播的所有消息 . 需要注意的是,缓存只能保留邮件很长时间 .
以下是用于将用户映射到其connectionId的数据库实现的链接
https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/mapping-users-to-connections#database