【发布时间】:2019-12-03 20:00:48
【问题描述】:
我在我的 asp.net Web 应用程序中使用 SignalR。 SignalR 集线器中不存在会话状态,因此我决定将 username <-> connectionId 对保存在静态字典中。
public static class UsernameConnectionsMaps
{
private static Dictionary<string, string> data = new Dictionary<string, string>();
public static void Add(string username, string connectionId)
{
data[username] = connectionId;
}
public static string Get(string username)
{
return data[username];
}
public static void Remove(string username)
{
return data.Remove(username);
}
}
在特定的控制器请求中,我想使用 signalR 向客户端发送数据。知道当前用户的用户名,我可以很容易地为客户端获取 connectionId 并发送数据。
我在控制器中使用Get 方法。
我在 hub 的 OnConnected() 和 OnDisconnected() 方法中分别使用了 Add 和 Remove 方法。
我感兴趣的是,此解决方案是否会对我的 Web 应用程序中的线程安全(或其他)有任何问题?有什么更好的方法?
【问题讨论】:
-
我假设任何给定点只有一个会话将用于一个用户
-
我能想到的主要问题是,如果应用程序池被回收(通常在 IIS 中定期自动发生),那么您将丢失内存中的连接列表,这显然会给您带来问题。最好将其保存在数据库之类的地方,恕我直言
-
如果你要使用字典,你应该使用ConcurrentDictionary 来保证线程安全。话虽如此,更常见的做法是将会话标识符存储在 cookie 中,使用加密随机标识符或某种形式的加密或防篡改。