我正在用asp.net MVC编写一个非常大的网络系统,它涉及根据他们订阅的内容向众多用户发送实时数据。
我和我的团队决定使用SignalR,我负责在系统中实现它。
在我们的例子中,用户选择要加入的组,然后选择1件事来处理。
为此,我将所有用户保存在数据库中。我将使用SignalR组来处理第一类,当我需要将消息推送给特定用户时(对于他正在挑选的另一件事),我只是从数据库中获取他的ConnectionID。 / p>
问题在于 - 每次刷新页面时(例如,当用户选择要加入的组时),他都会获得一个新的connectionID。现在他不会看到任何推向他的东西。
我在SignalR beta和版本2中看到了这一点(我在计算机上只有1.1.1)你可以制作自己的IUserIdProvider(测试版中的IUserIdPrefixGenerator)或IUserConnectionIdFactory等。所以我可以告诉他我希望他拥有的,但我似乎没有在我的SignalR版本中有任何这些。
答案 0 :(得分:0)
有很多方法可以解决这个问题,但也许最简单的方法之一就是将新的连接ID与用户关联起来(也许他们仍然在另一个标签中打开另一个连接)。这可以使用IP地址,用户代理,标头或位置的任意组合来完成。另一个很好的选择是要么使用会话,要么只是一个简单的标识符cookie(或多或少会话会做什么)。
我经常使用GUID,然后在创建新标识符cookie时在数据库中创建一个表。每次用户"刷新"或者打开一个新选项卡,可以在JS中读取cookie并使用hub.connect()
发送。然后,您可以在新连接ID和现有标识符cookie之间创建关联。
答案 1 :(得分:0)
我强烈建议您采用不同的方法来维护用户的 持久 连接。通常,我将所有用户连接ID保存在并发字典中,以允许对集合进行线程安全访问。每当发生断开事件时我都会从字典中删除用户,并且每当发生连接事件时我都会添加它们。
SignalR将为您管理用户的连接。对于您在数据库中执行此操作并与SignalR不同步,可以避免许多使其在首先正常工作的机制。
private readonly static Lazy<App> _instance = new Lazy<App>(
() => new App(GlobalHost.ConnectionManager.GetHubContext<AppHub>().Clients));
private readonly ConcurrentDictionary<string, User> _users = new ConcurrentDictionary<string, User>(StringComparer.OrdinalIgnoreCase);
private IHubConnectionContext Clients { get; set; }
public App(IHubConnectionContext clients)
{
Clients = clients;
}