public async Task OpenDoubleChatRoom(Models.OnlineUser invitee) { // Check this room is existed or not var invitor = _chatContext.GetOnlineUser(Context.UserIdentifier); var founDoubleRoom = _chatContext.GetDoubleRoom(invitor, invitee); string chatRoomId = string.Empty; string chatSessionId = string.Empty; bool isExistedOnDb = false; bool createNewSession = false; ChatSessionModel chatSessionModel = null; ChatSessionModel previousSessionModel = null; ChatRoomModel chatRoomModel = null; if (founDoubleRoom == null) { // Try to fetch from database var foundRoomInDb = (await _chatRoomRepository .GetAllAsync(a => a.Type == RoomType.Double && a.Participants.Any(b => b.Username == Context.UserIdentifier) && a.Participants.Any(c => c.Username == invitee.UserName))).FirstOrDefault(); if (foundRoomInDb != null) { chatRoomModel = new Models.ChatRoomModel { ChatRoomId = foundRoomInDb.Id, Participants = new System.Collections.Generic.List <Models.OnlineUser> { invitor, invitee }, RoomName = invitee.FullName, Type = RoomType.Double, CreateDate = DateTime.UtcNow }; _chatContext.LoadDoubleRoom(chatRoomModel); isExistedOnDb = true; chatRoomId = foundRoomInDb.Id; } else { // Create new chatroom var chatRoom = new ChatRoom { Id = DataUtil.GenerateUniqueId(), CreatedDate = DateTime.UtcNow, Participants = new List <Participant> { new Participant { Id = DataUtil.GenerateUniqueId(), JoinedDate = DateTime.UtcNow, Username = invitor.UserName }, new Participant { Id = DataUtil.GenerateUniqueId(), JoinedDate = DateTime.UtcNow, Username = invitee.UserName } }, RoomName = invitee.UserName, Sessions = new List <ChatSession>(), Type = RoomType.Double }; await _chatRoomRepository.AddAsync(chatRoom); chatRoomModel = new Models.ChatRoomModel { ChatRoomId = chatRoom.Id, Participants = new System.Collections.Generic.List <Models.OnlineUser> { invitor, invitee }, RoomName = invitee.FullName, Type = RoomType.Double, CreateDate = DateTime.UtcNow }; _chatContext.LoadDoubleRoom(chatRoomModel); chatRoomId = chatRoom.Id; createNewSession = true; } } else { chatRoomId = founDoubleRoom.ChatRoomId; chatRoomModel = founDoubleRoom; chatSessionModel = _chatContext.GetCurrentChatSession(chatRoomId); if (chatSessionModel == null) { createNewSession = true; } else if (!string.IsNullOrEmpty(chatSessionModel.PreviousSessionId)) { previousSessionModel = _chatContext.GetChatSession(chatSessionModel.PreviousSessionId); } } if (isExistedOnDb) { // Try to fetch last chat session var foundLastSession = await _chatSessionRepository.GetLastChatSession(chatRoomId); if (foundLastSession != null) { // In mind, we only create new chat session when it reached Threshold // Or it belongs to previous day if (foundLastSession.Conversations.Count >= _chatOptions.CurrentValue.ThresholdNumberOfMessages) { createNewSession = true; // Load previous session previousSessionModel = new ChatSessionModel { ChatRoomId = chatRoomId, Messages = new Queue <MessageModel>(), CreatedDate = foundLastSession.CreatedDate, PreviousSessionId = foundLastSession.PreviousSessionId, SessionId = foundLastSession.Id }; if (foundLastSession.Conversations != null) { foreach (var message in foundLastSession.Conversations.OrderBy(a => a.Timestamp)) { previousSessionModel.Messages.Enqueue(new MessageModel { Message = message.Message, FormattedMessage = message.MessageTransform, TimeStamp = message.Timestamp, UserName = message.Username, CreatedDate = message.CreatedDate, AttachmentFiles = new List <AttachmentFile>() }); } } _chatContext.AddChatRoomSession(previousSessionModel); } else { chatSessionModel = ChatSessionModel.LoadFrom(foundLastSession); // Load one previous session if it had if (!string.IsNullOrEmpty(chatSessionModel.PreviousSessionId)) { var previousSession = await _chatSessionRepository.GetOneAsync(chatSessionModel.PreviousSessionId); previousSessionModel = ChatSessionModel.LoadFrom(previousSession); } _chatContext.AddChatRoomSession(chatSessionModel); } } else { createNewSession = true; } } if (createNewSession) { chatSessionModel = new ChatSessionModel { SessionId = DataUtil.GenerateUniqueId(), ChatRoomId = chatRoomId, Messages = new Queue <MessageModel>(), CreatedDate = DateTime.UtcNow, PreviousSessionId = previousSessionModel?.SessionId }; if (previousSessionModel != null) { previousSessionModel.NextSessionId = chatSessionModel.SessionId; } _chatContext.AddChatRoomSession(chatSessionModel); } // Allow target user to prepare a chatroom await Clients .User(invitee.UserName) .ReadyDoubleChatRoom( chatRoomModel, chatSessionModel, invitor, previousSessionModel); await Clients.Caller.LoadDoubleChatRoom( chatRoomModel, chatSessionModel, invitee, previousSessionModel); }