private void frm_create_group_Load(object sender, EventArgs e)
        {
            var req = new http._User_Relation.FetchFriendListReq()
            {
                UserId = Class1.UserId
            };
            var resp = http._User_Relation.FetchFriendList(req);

            foreach (var user in resp.OnlineUsers)
            {
                clb_friend.Items.Add($"{user.NickName}({user.Id})", false);
            }
            foreach (var user in resp.OfflineUsers)
            {
                clb_friend.Items.Add($"{user.NickName}({user.Id})", false);
            }
        }
Ejemplo n.º 2
0
        public void LoadMain()
        {
            ChatListBox.Items.Clear();
            ChatListBox.Items.Add(new ChatListItem("好友", true));

            Class1.chatListSubItemPool.Clear();
            Class1.onlineUserId.Clear();
            Class1.offlineUserId.Clear();


            Class1.frmMsgBox.clb_unread_msg.Items.Clear();
            Class1.frmMsgBox.clb_unread_msg.Items.Add(new ChatListItem("个人消息", true));
            Class1.frmMsgBox.clb_unread_msg.Items.Add(new ChatListItem("系统消息", true));
            Class1.frmMsgBox.clb_unread_msg.Items.Add(new ChatListItem("群消息", true));


            Class1.groupItemPool.Clear();
            ChatListBox.Items.Add(new ChatListItem("群组", true));

            //throw new Exception("");

            Thread t1 = new Thread(new ThreadStart(() =>
            {
                while (Class1.IsOnline)
                {
                    /*
                     * 拉取好友列表
                     */
                    var req = new http._User_Relation.FetchFriendListReq()
                    {
                        UserId = Class1.UserId
                    };
                    var resp = http._User_Relation.FetchFriendList(req);
                    if (resp.StatusCode == 254)
                    {
                        return;
                    }

                    foreach (var user in resp.OnlineUsers)
                    {
                        Class1.updateUserId2User(user.Id, new Class1.User()
                        {
                            Id = user.Id, NickName = user.NickName
                        });
                    }
                    foreach (var user in resp.OfflineUsers)
                    {
                        Class1.updateUserId2User(user.Id, new Class1.User()
                        {
                            Id = user.Id, NickName = user.NickName
                        });
                    }

                    var oldOnlineUserId  = Class1.onlineUserId;
                    var oldOfflineUserId = Class1.offlineUserId;
                    var oldTotalUserId   = new HashSet <long>();
                    oldTotalUserId.UnionWith(oldOnlineUserId);
                    oldTotalUserId.UnionWith(oldOfflineUserId);

                    var newOnlineUserId  = new HashSet <long>();
                    var newOfflineUserId = new HashSet <long>();
                    var newTotalUserId   = new HashSet <long>();

                    foreach (var user in resp.OnlineUsers)
                    {
                        newOnlineUserId.Add(user.Id);
                    }
                    foreach (var user in resp.OfflineUsers)
                    {
                        newOfflineUserId.Add(user.Id);
                    }

                    newTotalUserId.UnionWith(newOnlineUserId);
                    newTotalUserId.UnionWith(newOfflineUserId);

                    //分配新增的subItem
                    foreach (var userId in newTotalUserId)
                    {
                        if (!oldTotalUserId.Contains(userId))
                        {
                            var subItem         = new ChatListSubItem(userId.ToString());
                            subItem.ID          = (uint)userId;
                            subItem.DisplayName = Class1.UserId2User[userId].NickName;
                            subItem.NicName     = userId.ToString();
                            subItem.Status      = ChatListSubItem.UserStatus.OffLine;
                            Class1.chatListSubItemPool.Add(userId, subItem);
                            Invoke(new Action(() =>
                            {
                                ChatListBox.Items[0].SubItems.Add(subItem);
                            }));
                            //新增好友后,拉取历史消息
                            var dt1 = Class1.sql.SqlTable($"SELECT count(*) as count FROM `message` WHERE (user_id_send = {Class1.UserId} AND user_id_recv = {userId}) OR (user_id_send = {userId} AND user_id_recv = {Class1.UserId})");
                            if (dt1 == null || dt1.Rows.Count != 1)
                            {
                                throw new Exception("select count(*) from message failed");
                            }

                            var localCount = long.Parse(dt1.Rows[0]["count"].ToString());
                            var fetchFriendHistoryMessageReq = new http._Message.FetchFriendHistoryMessageReq()
                            {
                                UserIdAlice = Class1.UserId,
                                UserIdBob   = userId,
                                LocalCount  = localCount
                            };
                            var fetchFriendHistoryMessageResp = http._Message.FetchFriendHistoryMessage(fetchFriendHistoryMessageReq);
                            if (fetchFriendHistoryMessageResp.StatusCode == 254)
                            {
                                return;
                            }
                            foreach (var obj in fetchFriendHistoryMessageResp.Objects)
                            {
                                Class1.InsertObjectIfNotExists(obj.Id, obj.ETag, obj.Name);
                            }
                            foreach (var msg in fetchFriendHistoryMessageResp.Messages)
                            {
                                if (msg.ContentType == (int)Class1.ContentType.Image)
                                {
                                    Class1.FetchImage(msg.Content);
                                }
                                var contentParam = Class1.Gzip(System.Text.Encoding.Default.GetBytes(msg.Content));
                                Class1.InsertMessageIfNotExists(msg.Id, msg.UserIdSend, msg.UserIdRecv, msg.GroupId, contentParam, msg.CreateTime, msg.ContentType, msg.MsgType);
                            }
                        }
                    }

                    Class1.onlineUserId  = newOnlineUserId;
                    Class1.offlineUserId = newOfflineUserId;

                    //销毁删除的subItem
                    foreach (var userId in oldTotalUserId)
                    {
                        if (!newTotalUserId.Contains(userId))
                        {
                            var subItem = Class1.chatListSubItemPool[userId];
                            Invoke(new Action(() =>
                            {
                                ChatListBox.Items[0].SubItems.Remove(subItem);
                            }));
                            Class1.chatListSubItemPool.Remove(userId);
                        }
                    }
                    foreach (var userId in newOnlineUserId)
                    {
                        Class1.chatListSubItemPool[userId].Status = ChatListSubItem.UserStatus.Online;
                    }
                    foreach (var userId in newOfflineUserId)
                    {
                        Class1.chatListSubItemPool[userId].Status = ChatListSubItem.UserStatus.OffLine;
                    }

                    icon.ChangeIconState();

                    /*
                     * 拉取群组列表
                     */
                    var fetchGroupListReq = new http._Group_User.FetchGroupListReq()
                    {
                        UserId = Class1.UserId
                    };
                    var fetchGroupListResp = http._Group_User.FetchGroupList(fetchGroupListReq);
                    if (fetchGroupListResp.StatusCode == 254)
                    {
                        return;
                    }

                    var oldGroupIds = new HashSet <long>();
                    var newGroupIds = new HashSet <long>();

                    foreach (var item in Class1.groupItemPool)
                    {
                        oldGroupIds.Add(item.Key);
                    }

                    foreach (var group in fetchGroupListResp.Groups)
                    {
                        newGroupIds.Add(group.Id);
                        Class1.updateGroupId2Group(group.Id, group);
                    }

                    foreach (var groupId in oldGroupIds)
                    {
                        if (!newGroupIds.Contains(groupId))
                        {
                            var subItem = Class1.groupItemPool[groupId];
                            Invoke(new Action(() =>
                            {
                                ChatListBox.Items[1].SubItems.Remove(subItem);
                            }));
                            Class1.groupItemPool.Remove(groupId);
                        }
                    }

                    foreach (var groupId in newGroupIds)
                    {
                        if (!oldGroupIds.Contains(groupId))
                        {
                            var subItem         = new ChatListSubItem(Class1.GetGroupInfo(groupId).Name);
                            subItem.ID          = (uint)groupId;
                            subItem.NicName     = groupId.ToString();
                            subItem.DisplayName = Class1.GetGroupInfo(groupId).Name;
                            Invoke(new Action(() =>
                            {
                                ChatListBox.Items[1].SubItems.Add(subItem);
                            }));
                            Class1.groupItemPool.Add(groupId, subItem);


                            //新增群组后,拉取历史消息
                            var dt1 = Class1.sql.SqlTable($"SELECT count(*) as count FROM `message` WHERE group_id = {groupId}");
                            if (dt1 == null || dt1.Rows.Count != 1)
                            {
                                throw new Exception("select count(*) from message failed");
                            }

                            var localCount = long.Parse(dt1.Rows[0]["count"].ToString());
                            var fetchGroupHistoryMessageReq = new http._Message.FetchGroupHistoryMessageReq()
                            {
                                GroupId    = groupId,
                                LocalCount = localCount
                            };
                            var fetchGroupHistoryMessageResp = http._Message.FetchGroupHistoryMessage(fetchGroupHistoryMessageReq);
                            if (fetchGroupHistoryMessageResp.StatusCode == 254)
                            {
                                return;
                            }
                            foreach (var obj in fetchGroupHistoryMessageResp.Objects)
                            {
                                Class1.InsertObjectIfNotExists(obj.Id, obj.ETag, obj.Name);
                            }
                            foreach (var msg in fetchGroupHistoryMessageResp.Messages)
                            {
                                if (msg.ContentType == (int)Class1.ContentType.Image)
                                {
                                    Class1.FetchImage(msg.Content);
                                }
                                var contentParam = Class1.Gzip(System.Text.Encoding.Default.GetBytes(msg.Content));
                                Class1.InsertMessageIfNotExists(msg.Id, msg.UserIdSend, msg.UserIdRecv, msg.GroupId, contentParam, msg.CreateTime, msg.ContentType, msg.MsgType);
                            }
                        }
                    }

                    updateRequestStatus();

                    Thread.Sleep(2 * 1000);
                }
                ;
            }));

            t1.Start();

            Thread t2 = new Thread(new ThreadStart(() =>    //异步拉取消息
            {
                var fetchGroupListReq = new http._Group_User.FetchGroupListReq()
                {
                    UserId = Class1.UserId
                };
                var fetchGroupListResp = http._Group_User.FetchGroupList(fetchGroupListReq);
                var groupIds           = new List <long>();
                foreach (var group in fetchGroupListResp.Groups)
                {
                    groupIds.Add(group.Id);
                }
                long messageId = -1, userRelationId = -1, groupUserId = -1;
                DataTable dt   = Class1.sql.SqlTable($"SELECT count(*) as count, MAX(id) as id FROM `message` WHERE (`user_id_send` = {Class1.UserId} OR `user_id_recv` = {Class1.UserId} OR `group_id` IN ({String.Join(",", groupIds)}))");
                if (dt != null && dt.Rows.Count == 1 && (long)dt.Rows[0]["count"] > 0)
                {
                    messageId = (long)dt.Rows[0]["id"];
                }
                dt = Class1.sql.SqlTable($"SELECT count(*) as count, MAX(id) as id FROM `user_relation_request` WHERE (`user_id_send` = {Class1.UserId} OR `user_id_recv` = {Class1.UserId})");
                if (dt != null && dt.Rows.Count == 1 && (long)dt.Rows[0]["count"] > 0)
                {
                    userRelationId = (long)dt.Rows[0]["id"];
                }
                dt = Class1.sql.SqlTable($"SELECT count(*) as count, MAX(id) as id FROM `group_user_request`");
                if (dt != null && dt.Rows.Count == 1 && (long)dt.Rows[0]["count"] > 0)
                {
                    groupUserId = (long)dt.Rows[0]["id"];
                }
                var req = new http._Message.SyncMessageReq()
                {
                    UserId         = Class1.UserId,
                    MessageId      = messageId,
                    UserRelationId = userRelationId,
                    GroupUserId    = groupUserId
                };
                var resp          = http._Message.SyncMessage(req);
                var messages      = resp.Messages;
                var userRelations = resp.UserRelations;
                var objects       = resp.Objects;
                var groupUsers    = resp.GroupUsers;
                //消息落库

                foreach (var obj in objects)
                {
                    Class1.InsertObjectIfNotExists(obj.Id, obj.ETag, obj.Name);
                }

                foreach (var msg in messages)
                {
                    if (msg.ContentType == (int)Class1.ContentType.Image)
                    {
                        Class1.FetchImage(msg.Content);
                    }
                    var param = Class1.Gzip(System.Text.Encoding.Default.GetBytes(msg.Content));
                    Class1.InsertMessageIfNotExists(msg.Id, msg.UserIdSend, msg.UserIdRecv, msg.GroupId, param, msg.CreateTime, msg.ContentType, msg.MsgType);
                }

                foreach (var msg in userRelations)
                {
                    bool ret1 = Class1.sql.ExecuteNonQuery($"INSERT INTO `user_relation_request`(id, user_id_send, user_id_recv, create_time, status, parent_id) VALUES({msg.Id}, " +
                                                           $"{msg.UserIdSend}, {msg.UserIdRecv}, {msg.CreateTime}, {msg.Status}, {msg.ParentId})");
                    if (!ret1)
                    {
                        MessageBox.Show("DB错误,INSERT INTO user_relation_request失败", "信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return;
                    }
                }

                foreach (var msg in groupUsers)
                {
                    bool ret1 = Class1.sql.ExecuteNonQuery($"INSERT INTO `group_user_request`(id, user_id_send, user_id_recv, group_id, create_time, status, parent_id, type) VALUES({msg.Id}, " +
                                                           $"{msg.UserIdSend}, {msg.UserIdRecv}, {msg.GroupId}, {msg.CreateTime}, {msg.Status}, {msg.ParentId}, {msg.Type})");
                    if (!ret1)
                    {
                        MessageBox.Show("DB错误,INSERT INTO group_user_request失败", "信息", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return;
                    }
                }

                //先同步地拉取status,防止LoadUnReadMessage读到脏数据
                updateRequestStatus();

                Class1.LoadUnReadMessage();

                Console.WriteLine("fetch offline message done");
            }));

            t2.Start();

            Thread t3 = new Thread(new ThreadStart(() =>    //心跳包
            {
                var req = new http._Heart_Beat.HeartBeatReq()
                {
                    UserId = Class1.UserId
                };
                while (Class1.IsOnline)
                {
                    http._Heart_Beat.HeartBeat(req);
                    Thread.Sleep(5 * 1000);
                }
            }));

            t3.Start();

            redis.Subscribe("poseidon_message_channel_" + Class1.UserId, MessageChannel);
            Class1.UpdateStatusCheckBox(Class1.IsOnline);
            Class1.InvokeToolStripStatusLabel(toolStripStatusLabel1, "在线");
            toolStripStatusLabel2.Text = Class1.FormatDateTime(DateTime.Now);
            notifyIcon1.Text           = $"{Class1.UserId2User[Class1.UserId].NickName}({Class1.UserId})";
            this.Text = $"{Class1.UserId2User[Class1.UserId].NickName}({Class1.UserId})";

            foreach (var item in Class1.formGroupPool)
            {
                var frmGroup = item.Value;
                frmGroup.login();
            }
        }