async Task OnMessageArrived (Message msg)
		{
			try {
				await conversationLoadTaskCompletionSource.Task; //prevent adding a new conversation before all conversations are loaded
				await newMessagesSemaphore.WaitAsync ();
				await UpdateConversationsWith (msg);
				newMessagesSemaphore.Release ();
			} catch (Exception ex) {
				App.Logger.Report (ex);
			}
		}
示例#2
0
        public async Task<SendMessageResult> SendMessageAsync(Message message)
        {
            try
            {
                Dictionary<string, byte[]> keys = null;
                string text = message.Text;

                await messageRepository.AddMessageAsync(message);

                if (EncryptionEnabled)
                {
                    var deviceIdAndPublicKeyMap = await deviceInfoProvider.GetUserDevicesAndPublicKeys((int) message.Recipient);
                    if (deviceIdAndPublicKeyMap.Count > 0)
                    {
                        //don't forget current user's other devices
                        var myDevices = await deviceInfoProvider.GetUserDevicesAndPublicKeys(Settings.MyId);
                        foreach (var myDevice in myDevices)
                        {
                            if (myDevice.Key != Settings.UserDeviceId && myDevice.Key != Settings.MyId.ToString())
                                deviceIdAndPublicKeyMap[myDevice.Key] = myDevice.Value;
                        }
                        text = cryptoService.Encrypt(message.Text, deviceIdAndPublicKeyMap, out keys);
                    }
                }

                var request = new SendMessageRequest
                    {
                        ReceiverUserId = message.Recipient,
                        SenderName = Settings.NickName,
                        MessageType = ServerClient.Entities.Ws.Requests.MessageType.Text,
                        MessageToken = message.MessageToken,
                        Thumbnail = message.Thumbnail,
                        GroupId = message.GroupId,
                        Message = text,
                        Keys = keys,
                    };

                var response = await messagingService.SendMessage(request);
                if (response.Error == Errors.SendMessage_ProvideKeysForTheseDevices)
                {
                    foreach (var item in response.MissedDevicesWithPublicKeysToReEncrypt)
                    {
                        await deviceInfoProvider.SavePublicKeyForDeviceId(item.DeviceId, item.UserId, Convert.ToBase64String(item.PublicKey));
                    }
                    //try again
                    return await SendMessageAsync(message);
                }
                if (response.Error == Errors.SendMessage_ReceiversNotFound)
                {
                    return SendMessageResult.ReceiverUnknown;
                }
                if (response.Error == Errors.SendMessage_ReceiverAndSenderAreSame)
                {
                    return SendMessageResult.ReceiverAndSenderAreSame;
                }

                OnMessageSent(message.MessageToken);
                return SendMessageResult.Ok;
            }
            catch (ConnectionException)
            {
                return SendMessageResult.ConnectionError;
            }
            catch (Exception ex)
            {
				App.Logger.Report (ex);
                return SendMessageResult.UnknownError;
            }
        }
示例#3
0
        private async void OnIncomingMessages(IEnumerable<IncomingMessage> messages)
        {
            if (messages == null)
            {
                return;
            }

            var incomingMessages = messages.Where(m => m.GroupId == Guid.Empty /*not supported yet*/).OrderBy(m => m.Time).ToList();
            foreach (var msg in incomingMessages)
            {
                string decryptedText = msg.Text;
                try
                {
                    if (msg.EncryptionKey != null && msg.EncryptionKey.Length > 0)
                    {
                        decryptedText = cryptoService.Decrypt(msg.Text, msg.EncryptionKey);
                    }
                }
                catch (Exception)
                {
                    decryptedText = DecryptionErrorMessage;
                }

                var dbMessage = new Message(msg.MessageToken, msg.EventId, msg.Time, msg.ToUserId, msg.FromUserId, decryptedText, msg.Thumbnail, MessageStatus.Delivered);
                await messageRepository.AddMessageAsync(dbMessage);
                MessageArrived(this, new MessageEventArgs { Message = dbMessage });
            }

            SendMessageAck(incomingMessages.Select(m => m.EventId).ToList());
        }
示例#4
0
        public async Task MarkMessageAsSeen(Message message)
        {
            if (Settings.MyId == message.Sender)
            {
                //multi-device message
                return;
            }

            await messagingService.MarkMessageAsSeen(new MarkMessageAsSeenRequest
                {
                    MessagesAuthor = message.Sender,
                    MessagesSeen = new List<Guid> {message.MessageToken}
                });
            message.Status = MessageStatus.Seen;
            await messageRepository.UpdateMessageStatusAsync(message.MessageToken, message.Status);
        }
		public async Task SendMessage(string text, byte[] image = null)
        {
		    try
			{
                currentUserTypingController.HandleOutgoingMessage();
				Settings.KinderPoints = Settings.KinderPoints + 1;

                await messageLoadTaskCompletionSource.Task;
				App.ConversationsViewModel.IsDirty = true;
                var message = new Message(Guid.NewGuid(), Guid.Empty, DateTime.UtcNow, recipientId, Settings.MyId, text, image, MessageStatus.Unsent);

                Messages.Add(MessageViewModelFactory.Create(message));

                //chatting with fake contacts
				if (recipientId < 0)
                {
					dataManager.AddMessageAsync(message);
					return;
				}

			    var sendMessageResult = await App.MessagesManager.SendMessageAsync(message);
                switch (sendMessageResult)
                {
                    case SendMessageResult.Ok:
                        break;
                    case SendMessageResult.ConnectionError:
                        App.MessageDialog.SendMessage("Internet connection is required", "No service");
                        break;
                    case SendMessageResult.ReceiverUnknown:
                        App.MessageDialog.SendMessage("Receiver was not found on the server", "Error");
                        break;
                    case SendMessageResult.ReceiverAndSenderAreSame:
                        App.MessageDialog.SendMessage("That's you!", "Error");
                        break;
                    case SendMessageResult.UnknownError:
                        App.MessageDialog.SendMessage("Oops... something went wrong", "Error");
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }


			    App.Logger.Track("SendMessage");
		    }
		    catch (Exception ex)
            {
				App.Logger.Report (ex);
                App.MessageDialog.SendMessage("Message wasn't sent", "Oops..");
		    }
		}
		async Task UpdateConversationsWith (Message incomingMsg)
		{
			Message existingConversation = conversations.FirstOrDefault (c => c.ConversationId == incomingMsg.ConversationId);
			if (existingConversation != null)
				ReplaceConversation (existingConversation, incomingMsg);
			else
				await AddConversation (incomingMsg);
		}
		void CopyNamePhoto (Message src, Message dst)
		{
			dst.FriendPhoto = src.FriendPhoto;
			dst.FriendName = src.FriendName;
		}
		async Task<Friend> GetFriend (Message msg)
		{
			long id = GetFriendId (msg);
			var friend = await DataManager.GetFriendAsync (id);

			if (friend == null) {
				friend = new Friend { FriendId = id, Name = string.Empty };
				await App.FriendsViewModel.UpdateFriendInfoAsync (friend);
			}

			return friend;
		}
		long GetFriendId (Message msg)
		{
			// This is equivalent to Settings.MyId == msg.Recipient ? msg.Sender : msg.Recipient;
			// but has a simmetry between Sender and msg.Recipient
			return Settings.MyId ^ (msg.Recipient ^ msg.Sender);
		}
		async Task FillNameAndPhoto (Message msg)
		{
			var friend = await GetFriend (msg);
			CopyNamePhoto (friend, msg);
		}
		async Task AddConversation (Message incomingMsg)
		{
			await FillNameAndPhoto (incomingMsg);
			conversations.Insert (0, incomingMsg);
		}
		void ReplaceConversation (Message existingConversation, Message incomingMsg)
		{
			conversations.Remove (existingConversation);
			CopyNamePhoto (existingConversation, incomingMsg);
			conversations.Insert (0, incomingMsg); //new conversation on the top
		}
示例#13
0
	    public async Task<bool> AddMessageAsync(Message message)
	    {		    
            //using (await LockAsync())
            {
                Message existingMsg = null;
                if (message.MessageToken != Guid.Empty)
                {
                    //ignore duplicates (by Token) - it may happen
                    existingMsg = await database.GetItemAsync<Message>(msg => msg.MessageToken == message.MessageToken);
                    if (existingMsg != null && message.Id < 1)
                    {
                        message.Id = existingMsg.Id;
                    }
                }
                await database.SaveItemAsync<Message>(message);
                return existingMsg == null;
		    }
	    }
示例#14
0
		void HandleStatusChanged(Message message, int index) 
		{
			
		}