Пример #1
0
        /// <summary>
        /// Загружает чат по указанному идентификатору и возвращает его.
        /// </summary>
        /// <param name="chatID">Идентификатор чата.</param>
        /// <exception cref="CacheConversationException"/>
        /// <exception cref="AuthorizationRequiredException"/>
        public Task <IChat> GetChat(uint chatID)
        {
            return(chatsTasks.GetOrAdd(chatID, async id =>
            {
                if (cacheService == null)
                {
                    cacheService = ServiceLocator.Current.GetInstance <IMessagesCacheService>();
                }

                Task <IChat> completedTask = null;
                var request = new GetChatRequest
                {
                    ChatID = id,
                    Fields = new List <VKUserFields> {
                        VKUserFields.photo_50, VKUserFields.sex, VKUserFields.online
                    }
                };

                for (int i = 0; i < MAX_ATTEMPTS_NUMBER; i++)
                {
                    var response = await request.ExecuteAsync();

                    if (response.Error.ErrorType == VKErrors.AccessDenied || response.Error.ErrorType == VKErrors.AuthorizationFailed)
                    {
                        chatsTasks.TryRemove(id, out completedTask);
                        throw new AuthorizationRequiredException("Запрос провалился из-за необходимости выполнить авторизацию.");
                    }
                    if (response.Error.ErrorType != VKErrors.None)
                    {
                        if (i + 1 < MAX_ATTEMPTS_NUMBER)
                        {
                            await Task.Delay(1000);
                        }
                        continue;
                    }

                    IChat chat = new Chat();
                    chat.AdminID = response.Response.AdminID;
                    chat.ChatID = response.Response.ID;
                    chat.Title = response.Response.Title;
                    chat.Messages = new MessagesCollection(response.Response.ID);
                    chat.Users = new ObservableCollection <VKProfileChat>(response.Response.Users);

                    await cacheService.CacheConversation(chat);

                    chatsTasks.TryRemove(id, out completedTask);
                    return chat;
                }

                chatsTasks.TryRemove(id, out completedTask);
                throw new CacheConversationException("Не удалось загрузить информацию о чате.");
            }));
        }
Пример #2
0
        /// <summary>
        /// Возвращает кортеж из беседы и коллекции сообщений.
        /// </summary>
        /// <param name="convID">Идентификатор беседы.</param>
        public async Task <Tuple <CachedConversationOld, MessagesCollection> > GetMessages(long convID)
        {
            var pair = Conversations.FirstOrDefault(p => p.Key.ID == convID);

            if (pair.Key != null && pair.Value != null)
            {
                return(new Tuple <CachedConversationOld, MessagesCollection>(pair.Key, pair.Value));
            }

            MessagesCollection msgs = null;

            if (convID < 0)
            {
                msgs = new MessagesCollection((uint)-convID);
            }
            else
            {
                msgs = new MessagesCollection((ulong)convID);
            }

            var cache = await ServiceHelper.MessagesCacheService.GetConversationFromCache(convID);

            if (cache != null)
            {
                for (int i = 0; i < cache.Users.Count; i++)
                {
                    ulong userID = cache.Users[i].ID;
                    var   user   = CachedUsers.Values.FirstOrDefault(u => u.ID == userID);

                    if (user != null)
                    {
                        cache.Users[i] = user;
                    }
                    else
                    {
                        CachedUsers[userID] = cache.Users[i];
                    }
                }

                foreach (var msg in cache.CachedMessages)
                {
                    if (cache.Users != null)
                    {
                        msg.Sender = cache.Users.FirstOrDefault(u => u.ID == msg.UserID);
                    }
                    msgs.Add(msg);
                }
                msgs.Unread          = cache.Unread;
                Conversations[cache] = msgs;

                return(new Tuple <CachedConversationOld, MessagesCollection>(cache, msgs));
            }

            if (convID < 0)
            {
                bool success      = false;
                byte numOfRetries = 0;
                while (!success && numOfRetries <= 3)
                {
                    var request = new GetChatRequest()
                    {
                        ChatID   = -convID,
                        IsSingle = true,
                        Fields   = new List <VKUserFields> {
                            VKUserFields.photo_50, VKUserFields.online, VKUserFields.sex
                        }
                    };
                    var response = await request.ExecuteAsync();

                    if (response.Error.ErrorType == VKErrors.None)
                    {
                        success = true;
                        cache   = new CachedConversationOld
                        {
                            ID    = convID,
                            Title = response.Response.Title,
                            Users = new ObservableCollection <VKProfileChat>(response.Response.Users)
                        };
                        Conversations[cache] = msgs;
                        foreach (var user in cache.Users)
                        {
                            CachedUsers[user.ID] = user;
                        }

                        //msgs.UpdateSimilar();
                        return(new Tuple <CachedConversationOld, MessagesCollection>(cache, msgs));
                    }
                    else
                    {
                        numOfRetries++;
                        CoreHelper.SendInAppPush(
                            "Ошибка соединения.\nПовтор через " + 3 * numOfRetries + " секунд",
                            null, PopupMessageType.Warning);
                        await Task.Delay(3000 *numOfRetries);
                    }
                }

                return(null);
            }
            else
            {
                bool success      = false;
                byte numOfRetries = 0;
                while (!success && numOfRetries <= 3)
                {
                    var request = new GetUsersRequest {
                        UserID = (ulong)convID
                    };
                    var response = await request.ExecuteAsync();

                    if (response.Error.ErrorType == VKErrors.None)
                    {
                        success = true;
                        var user = response.Response[0];
                        cache = new CachedConversationOld
                        {
                            ID    = convID,
                            Title = user.FullName,
                            Users = new ObservableCollection <VKProfileChat>
                            {
                                new VKProfileChat
                                {
                                    ID        = user.ID,
                                    LastName  = user.LastName,
                                    FirstName = user.FirstName,
                                    Photo50   = user.Photo50,
                                    Online    = user.Online,
                                    Sex       = user.Sex
                                }
                            }
                        };
                        Conversations[cache] = msgs;
                        CachedUsers[user.ID] = cache.Users[0];

                        return(new Tuple <CachedConversationOld, MessagesCollection>(cache, msgs));
                    }
                    else
                    {
                        numOfRetries++;
                        CoreHelper.SendInAppPush(
                            "Ошибка соединения.\nПовтор через " + 3 * numOfRetries + " секунд",
                            null, PopupMessageType.Warning);
                        await Task.Delay(3000 *numOfRetries);
                    }
                }

                return(null);
            }
        }
Пример #3
0
        /// <summary>
        /// Вызывается при получении новых сообщений через LongPoll.
        /// </summary>
        private async void VKLongPollService_MessagesReceived(object sender, MessagesReceivedEventArgs e)
        {
            var ids = new ulong[e.Messages.Count];

            for (int i = 0; i < e.Messages.Count; i++)
            {
                ids[i] = e.Messages[i].MessageID;
            }

            List <VKMessage> resultMessages = null;

            bool success      = false;
            byte numOfRetries = 0;

            while (!success && numOfRetries <= 3)
            {
                var request = new GetByIDRequest {
                    MessageIDs = ids.ToList()
                };
                var response = await request.ExecuteAsync();

                if (response.Error.ErrorType == VKErrors.None)
                {
                    success        = true;
                    resultMessages = response.Response.Items;
                }
                else
                {
                    numOfRetries++;
                    CoreHelper.SendInAppPush(
                        "Ошибка соединения.\nПовтор через " + 3 * numOfRetries + " секунд",
                        null, PopupMessageType.Warning);
                    await Task.Delay(3000 *numOfRetries);
                }
            }

            if (!success)
            {
                CoreHelper.SendInAppPush(
                    "Не удалось получить подробные сообщения",
                    "LongPoll", PopupMessageType.Error);
                return;
            }

            var unknownUsers = new Dictionary <ulong, List <VKMessage> >();

            var conversations = new Dictionary <long, List <VKMessage> >();

            foreach (var msg in resultMessages)
            {
                long key = msg.IsChatMessage ? -msg.ChatID : (long)msg.UserID;
                if (conversations.ContainsKey(key))
                {
                    conversations[key].Add(msg);
                }
                else
                {
                    var list = new List <VKMessage>();
                    list.Add(msg);
                    conversations[key] = list;
                }

                if (CachedUsers.ContainsKey(msg.UserID))
                {
                    msg.Sender = CachedUsers[msg.UserID];
                }
                else
                {
                    if (unknownUsers.ContainsKey(msg.UserID))
                    {
                        unknownUsers[msg.UserID].Add(msg);
                    }
                    else
                    {
                        var list = new List <VKMessage>();
                        list.Add(msg);
                        unknownUsers[msg.UserID] = list;
                    }
                }
            }

            success      = unknownUsers.Count == 0;
            numOfRetries = 0;
            while (!success && numOfRetries <= 3)
            {
                var usersRequest = new GetUsersRequest()
                {
                    UserIDs = unknownUsers.Keys.ToList()
                };
                var usersResponse = await usersRequest.ExecuteAsync();

                if (usersResponse.Error.ErrorType == VKErrors.None)
                {
                    success = true;
                    foreach (var user in usersResponse.Response)
                    {
                        var sUser = new VKProfileChat()
                        {
                            ID        = user.ID,
                            FirstName = user.FirstName,
                            LastName  = user.LastName,
                            Online    = user.Online,
                            Photo50   = user.Photo50
                        };

                        var list = unknownUsers[user.ID];
                        for (int i = 0; i < list.Count; i++)
                        {
                            list[i].Sender = sUser;
                        }

                        CachedUsers[sUser.ID] = sUser;
                    }
                }
                else
                {
                    numOfRetries++;
                    CoreHelper.SendInAppPush(
                        "Ошибка соединения.\nПовтор через " + 3 * numOfRetries + " секунд",
                        null, PopupMessageType.Warning);
                    await Task.Delay(3000 *numOfRetries);
                }
            }

            if (!success)
            {
                CoreHelper.SendInAppPush(
                    "Не удалось получить информацию о пользователях сообщений",
                    null, PopupMessageType.Error);
            }

            foreach (long convID in conversations.Keys)
            {
                var msgsList   = conversations[convID];
                var cachedConv = Conversations.Keys.FirstOrDefault(c => c.ID == convID);

                if (cachedConv != null)
                {
                    var list = Conversations[cachedConv];
                    foreach (var msg in msgsList)
                    {
                        list.Insert(0, msg);
                    }
                }
                else
                {
                    MessagesCollection list = null;
                    if (convID < 0)
                    {
                        list = new MessagesCollection((uint)-convID);
                    }
                    else
                    {
                        list = new MessagesCollection((ulong)convID);
                    }

                    cachedConv = await ServiceHelper.MessagesCacheService.GetConversationFromCache(convID);

                    if (cachedConv != null)
                    {
                        foreach (var msg in cachedConv.CachedMessages)
                        {
                            list.Add(msg);
                        }
                    }
                    else
                    {
                        if (convID < 0)
                        {
                            success      = false;
                            numOfRetries = 0;
                            while (!success && numOfRetries <= 3)
                            {
                                var request = new GetChatRequest()
                                {
                                    ChatID   = -convID,
                                    IsSingle = true,
                                    Fields   = new List <VKUserFields> {
                                        VKUserFields.photo_50, VKUserFields.online, VKUserFields.sex
                                    }
                                };
                                var response = await request.ExecuteAsync();

                                if (response.Error.ErrorType == VKErrors.None)
                                {
                                    success    = true;
                                    cachedConv = new CachedConversationOld
                                    {
                                        ID             = convID,
                                        Title          = response.Response.Title,
                                        Users          = new ObservableCollection <VKProfileChat>(response.Response.Users),
                                        CachedMessages = msgsList,
                                        AdminID        = response.Response.AdminID
                                    };
                                    Conversations[cachedConv] = list;

                                    foreach (var user in cachedConv.Users)
                                    {
                                        CachedUsers[user.ID] = user;
                                    }
                                }
                                else
                                {
                                    numOfRetries++;
                                    CoreHelper.SendInAppPush(
                                        "Ошибка соединения.\nПовтор через " + 3 * numOfRetries + " секунд",
                                        null, PopupMessageType.Warning);
                                    await Task.Delay(3000 *numOfRetries);
                                }
                            }
                        }
                        else
                        {
                            success      = false;
                            numOfRetries = 0;
                            while (!success && numOfRetries <= 3)
                            {
                                var request = new GetUsersRequest {
                                    UserID = (ulong)convID
                                };
                                var response = await request.ExecuteAsync();

                                if (response.Error.ErrorType == VKErrors.None)
                                {
                                    success = true;
                                    var user = response.Response[0];
                                    cachedConv = new CachedConversationOld
                                    {
                                        ID    = convID,
                                        Title = user.FullName,
                                        Users = new ObservableCollection <VKProfileChat>
                                        {
                                            new VKProfileChat
                                            {
                                                ID        = user.ID,
                                                LastName  = user.LastName,
                                                FirstName = user.FirstName,
                                                Photo50   = user.Photo50,
                                                Online    = user.Online
                                            }
                                        }
                                    };
                                    CachedUsers[user.ID] = cachedConv.Users[0];
                                }
                                else
                                {
                                    numOfRetries++;
                                    CoreHelper.SendInAppPush(
                                        "Ошибка соединения.\nПовтор через " + 3 * numOfRetries + " секунд",
                                        null, PopupMessageType.Warning);
                                    await Task.Delay(3000 *numOfRetries);
                                }
                            }
                        }
                    }

                    foreach (var msg in msgsList)
                    {
                        list.Insert(0, msg);
                    }

                    //list.UpdateSimilar();
                    Conversations[cachedConv] = list;
                }

                await CacheConversation(cachedConv.ID);

                WorkOnDialog(msgsList.Last());

                var lastMsg = msgsList.LastOrDefault(m => m.Type == VKMessageType.Received);
                if (lastMsg == null)
                {
                    continue;
                }

                var navParameter = new NavigateToPageMessage
                {
                    Page      = AppViews.ConversationView,
                    Parameter = convID
                };

                CoreHelper.SendInAppPush(lastMsg.Body,
                                         cachedConv.Title, PopupMessageType.Default,
                                         lastMsg.Sender.Photo50, parameter: navParameter);
            }

            await ServiceHelper.MessagesCacheService.CacheDialogs(Dialogs.Take(20).ToList());
        }