3000用户测试正常,超过5000用户 Redis和内存中数据不一样 总是差几个 下面是我的代码
1 public void UserConnected(string username,string terminalCategory,string nickname,string groupid,string groupname) 2 { 3 try 4 { 5 Terminal _TempTerminal; 6 7 var _Users = UserManager.Instance(); 8 9 10 11 if (_Users.ContainsKey(username)) 12 { 13 var _user = _Users.SingleOrDefault(o => o.Key == username); 14 15 if (_user.Value.Terminals.ContainsKey(terminalCategory)) 16 { 17 var _terminal = _user.Value.Terminals.SingleOrDefault(o => o.Key == terminalCategory); 18 19 _terminal.Value.ConnectedId= Context.ConnectionId; 20 _terminal.Value.ConnectedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); 21 _TempTerminal = _terminal.Value; 22 } 23 else 24 { 25 var terminal = new Terminal(); 26 terminal.Category = terminalCategory; 27 terminal.ConnectedId = Context.ConnectionId; 28 terminal.ConnectedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); 29 30 terminal.UserName = username; 31 terminal.NickName = nickname; 32 terminal.GroupId = groupid; 33 terminal.GroupName = groupname; 34 35 36 _user.Value.Terminals.Add(terminalCategory, terminal); 37 _TempTerminal = terminal; 38 } 39 40 } 41 else 42 { 43 var terminal = new Terminal(); 44 terminal.Category = terminalCategory; 45 terminal.ConnectedId = Context.ConnectionId; 46 terminal.ConnectedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); 47 48 terminal.UserName = username; 49 terminal.NickName = nickname; 50 terminal.GroupId = groupid; 51 terminal.GroupName = groupname; 52 53 54 User user = new User(); 55 Dictionary<string, Terminal> terminals = new Dictionary<string, Terminal>(); 56 57 terminals.Add(terminalCategory, terminal); 58 user.UserName = username; 59 user.Terminals = terminals; 60 user.NickName = nickname; 61 user.GroupId = groupid; 62 user.GroupName = groupname; 63 64 _Users.Add(username, user); 65 66 _TempTerminal = terminal; 67 } 68 69 70 71 72 RedisHelper RClient = new RedisHelper(); 73 RClient.SetEntryInHash(username, terminalCategory, JsonHelper.GetJson(_TempTerminal)); 74 75 Groups.Add(Context.ConnectionId, groupid); 76 77 string jsonContent = "{type:'online',username:'" + username + "'}"; 78 Clients.Caller.OnMessage(jsonContent); 79 } 80 catch (Exception ex) 81 { 82 83 logger.Error("UserConnected:" + ex.ToString()); 84 } 85 86 87 88 }
下面是我的类和单例
public class UserManager { private static Logger logger = LogManager.GetCurrentClassLogger(); private static Dictionary<string, User> users = null; private static readonly object syncRoot = new object(); private static readonly object syncRootRemove = new object(); private UserManager() { } public static Dictionary<string, User> Instance() { if (users == null) { lock (syncRoot) { if (users == null) { users = new Dictionary<string, User>(); } } } return users; } public static void RemoveUser(string ConnectionId) { lock (syncRootRemove) { foreach (var u in users) { try { var t = u.Value.Terminals.Values.FirstOrDefault(o => o.ConnectedId == ConnectionId); if (t != null) { var _tempUserName = ""; u.Value.Terminals.Remove(t.Category); IHubContext<IClient> Context = GlobalHost.ConnectionManager.GetHubContext<MyHub, IClient>(); Context.Groups.Remove(ConnectionId, u.Value.GroupId); RedisHelper RClient = new RedisHelper(); RClient.RemoveEntryFromHash(t.UserName, t.Category); if (u.Value.Terminals.Count <= 0) { _tempUserName = u.Value.UserName; users.Remove(u.Value.UserName); RClient.Remove(t.UserName); } string jsonContent = "{type:'offline',username:'" + u.Value.UserName + "'}"; Context.Clients.All.OnMessage(jsonContent); break; } } catch (Exception ex) { logger.Error("RemoveUser" + ex.ToString()); } } } } } public class User { public string UserName { get; set; } public string NickName { get; set; } public string GroupId { get; set; } public string GroupName { get; set; } public Dictionary<string,Terminal> Terminals { get; set; } } public class Terminal { public string UserName { get; set; } public string NickName { get; set; } public string GroupId { get; set; } public string GroupName { get; set; } public string Category { get; set; } public string ConnectedTime { get; set; } public string ConnectedId { get; set; } }
使用的是微软的SignalR
是测试单纯的Connected 不一致,还是既有add,也有remove?如果是后者建议你lock (syncRootRemove)都锁同一个对象
第一种,模拟了几千个用户登录
上了线程锁,自己解决的