首页 新闻 会员 周边 捐助

每秒100并发 5000用户的接入 通讯服务器 会发生数据异常

0
悬赏园豆:30 [已关闭问题] 关闭于 2017-08-11 11:06

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 

小猪熊V587的主页 小猪熊V587 | 初学一级 | 园豆:176
提问于:2017-08-10 11:13
< >
分享
所有回答(2)
0

是测试单纯的Connected 不一致,还是既有add,也有remove?如果是后者建议你lock (syncRootRemove)都锁同一个对象

czd890 | 园豆:14488 (专家六级) | 2017-08-10 11:45

第一种,模拟了几千个用户登录

支持(0) 反对(0) 小猪熊V587 | 园豆:176 (初学一级) | 2017-08-10 13:28
0

上了线程锁,自己解决的

小猪熊V587 | 园豆:176 (初学一级) | 2017-08-11 11:05
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册