Open Closed

Chat Module not working in abp microsevice blazor web assembly project #5211


User avatar
0
raju.thinnaluri@gmail.com created

Hi,

We implemented the Blazor WebAssembly app as a SaaS model in microservice template on abp 7.2.2 version

Added a Chat Module as a package. but chat page not loading. getting the below issue.

  • ABP Framework version: v7.2.2
  • UI type: Blazor WebAssembly
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no
  • Exception message and stack trace:
  • Steps to reproduce the issue:"

31 Answer(s)
  • User Avatar
    0
    raju.thinnaluri@gmail.com created

    Hi,

    Chat function between 2 users not working. the first user message receives to second user.

    but when second user sending message system throwing below error

    The Log:

    2023-06-10 11:52:32.988 +08:00 [INF] Request finished HTTP/1.1 GET https://localhost:44361/api/chat/conversation/conversation?TargetUserId=33ce5896-e31b-d81a-7ef7-3a0ba734965d&SkipCount=0&MaxResultCount=100&api-version=1.0 - 0 - 200 - application/json;+charset=utf-8 74.2784ms 2023-06-10 11:52:33.008 +08:00 [ERR] An exception occurred in the database while saving changes for context type 'NaviX.UnifiedDigitalPlatform.ProductService.EntityFrameworkCore.ProductServiceDbContext'. Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions. at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyExceptionAsync(RelationalDataReader reader, Int32 commandIndex, Int32 expectedRowsAffected, Int32 rowsAffected, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithRowsAffectedOnlyAsync(Int32 commandIndex, RelationalDataReader reader, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeAsync(RelationalDataReader reader, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Update.Internal.SqlServerModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList1 entriesToSave, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions. at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyExceptionAsync(RelationalDataReader reader, Int32 commandIndex, Int32 expectedRowsAffected, Int32 rowsAffected, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithRowsAffectedOnlyAsync(Int32 commandIndex, RelationalDataReader reader, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeAsync(RelationalDataReader reader, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Update.Internal.SqlServerModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList1 entriesToSave, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) 2023-06-10 11:52:33.031 +08:00 [ERR] ---------- RemoteServiceErrorInfo ---------- { "code": null, "message": "The data you have submitted has already changed by another user/client. Please discard the changes you've done and try from the beginning.", "details": null, "data": null, "validationErrors": null }

    2023-06-10 11:52:33.032 +08:00 [ERR] The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions. Volo.Abp.Data.AbpDbConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions. ---> Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions. at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyExceptionAsync(RelationalDataReader reader, Int32 commandIndex, Int32 expectedRowsAffected, Int32 rowsAffected, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithRowsAffectedOnlyAsync(Int32 commandIndex, RelationalDataReader reader, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeAsync(RelationalDataReader reader, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Update.Internal.SqlServerModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList1 entriesToSave, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Volo.Abp.EntityFrameworkCore.AbpDbContext1.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) --- End of inner exception stack trace --- at Volo.Abp.EntityFrameworkCore.AbpDbContext1.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Volo.Abp.Uow.UnitOfWork.SaveChangesAsync(CancellationToken cancellationToken) at Volo.Abp.AspNetCore.Mvc.Uow.AbpUowActionFilter.SaveChangesAsync(ActionExecutingContext context, IUnitOfWorkManager unitOfWorkManager) at Volo.Abp.AspNetCore.Mvc.Uow.AbpUowActionFilter.SaveChangesAsync(ActionExecutingContext context, IUnitOfWorkManager unitOfWorkManager) at Volo.Abp.AspNetCore.Mvc.Uow.AbpUowActionFilter.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) 2023-06-10 11:52:33.037 +08:00 [INF] Executing ObjectResult, writing value of type 'Volo.Abp.Http.RemoteServiceErrorResponse'. 2023-06-10 11:52:33.038 +08:00 [INF] Executed action Volo.Chat.Conversations.ConversationController.GetConversationAsync (Volo.Chat.HttpApi) in 97.6155ms 2023-06-10 11:52:33.038 +08:00 [INF] Executed endpoint 'Volo.Chat.Conversations.ConversationController.GetConversationAsync (Volo.Chat.HttpApi)' 2023-06-10 11:52:33.068 +08:00 [DBG] Added 0 entity changes to the current audit log 2023-06-10 11:52:33.069 +08:00 [DBG] Added 0 entity changes to the current audit log 2023-06-10 11:52:33.070 +08:00 [INF] Request finished HTTP/1.1 GET https://localhost:44361/api/chat/conversation/conversation?TargetUserId=b4b82d66-d14b-a8ac-fac8-3a0b83a99d0a&SkipCount=0&MaxResultCount=100&api-version=1.0 - 0 - 409 - application/json;+charset=utf-8 132.8456ms

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Please share the project with me, thanks.

  • User Avatar
    0
    raju.thinnaluri@gmail.com created

    Hi,

    I uploaded and shared the source code to you email id shiwei.liang@volosoft.com.

    you may check.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    We will check it.

  • User Avatar
    0
    raju.thinnaluri@gmail.com created

    Hi,

    is there any issue? may i get the solution

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    We will fix the problem in the next patch version.

    You can try this:

    [ExposeServices(typeof(IConversationAppService))]
    public class MyConversationAppService : ConversationAppService
    {
        private readonly MyMessagingManager _myMessagingManager;
        private readonly IChatUserLookupService _chatUserLookupService;
        public MyConversationAppService(
            MessagingManager messagingManager,
            IChatUserLookupService chatUserLookupService,
            IConversationRepository conversationRepository,
            IRealTimeChatMessageSender realTimeChatMessageSender,
            IAuthorizationService authorizationService,
            MyMessagingManager myMessagingManager) : base(messagingManager, chatUserLookupService, conversationRepository, realTimeChatMessageSender, authorizationService)
        {
            _chatUserLookupService = chatUserLookupService;
            _myMessagingManager = myMessagingManager;
        }
    
        public override async Task<ChatConversationDto> GetConversationAsync(GetConversationInput input)
        {
    
            var targetUser = await _chatUserLookupService.FindByIdAsync(input.TargetUserId);
            if (targetUser == null)
            {
                throw new BusinessException("Volo.Chat:010003");
            }
    
            var chatConversation = new ChatConversationDto
            {
                TargetUserInfo = new ChatTargetUserInfo
                {
                    UserId = targetUser.Id,
                    Name = targetUser.Name,
                    Surname = targetUser.Surname,
                    Username = targetUser.UserName,
                },
                Messages = new List<ChatMessageDto>()
            };
    
            var messages = await _myMessagingManager.ReadMessagesAsync(targetUser.Id, input.SkipCount, input.MaxResultCount);
    
            chatConversation.Messages.AddRange(
                messages.Select(x => new ChatMessageDto
                {
                    Message = x.Message.Text,
                    MessageDate = x.Message.CreationTime,
                    ReadDate = x.Message.ReadTime ?? DateTime.MaxValue,
                    IsRead = x.Message.IsAllRead,
                    Side = x.UserMessage.Side
                })
            );
    
    
            return chatConversation;
        }
    }
    
    [ExposeServices(typeof(MessagingManager), typeof(MyMessagingManager))]
    public class MyMessagingManager : MessagingManager
    {
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly IUserMessageRepository _userMessageRepository;
        private readonly IConversationRepository _conversationRepository;
        private readonly IMessageRepository _messageRepository;
    
        public MyMessagingManager(
            IMessageRepository messageRepository,
            IUserMessageRepository userMessageRepository,
            IChatUserLookupService chatUserLookupService,
            IConversationRepository conversationRepository,
            ICurrentUser currentUser,
            IUnitOfWorkManager unitOfWorkManager)
            : base(messageRepository, userMessageRepository, chatUserLookupService, conversationRepository, currentUser)
        {
            _messageRepository = messageRepository;
            _userMessageRepository = userMessageRepository;
            _conversationRepository = conversationRepository;
            _unitOfWorkManager = unitOfWorkManager;
        }
    
    
        public new async Task<List<MessageWithDetails>> ReadMessagesAsync(Guid targetUserId, int skipCount, int maxResultCount)
        {
            var messages = await _userMessageRepository.GetMessagesAsync(CurrentUser.GetId(), targetUserId, skipCount, maxResultCount);
    
            //TODO: Optimize
            var readMessages = new List<Message>();
            foreach (var message in messages.Where(m => !m.UserMessage.IsRead).ToArray())
            {
                message.UserMessage.MarkAsRead(Clock.Now);
                await _userMessageRepository.UpdateAsync(message.UserMessage);
    
                message.Message.MarkAsAllRead(Clock.Now);
                readMessages.Add(message.Message);
            }
    
            var conversationPair = await _conversationRepository.FindPairAsync(CurrentUser.GetId(), targetUserId);
            if (conversationPair != null)
            {
                conversationPair.SenderConversation.ResetUnreadMessageCount();
    
                await _conversationRepository.UpdateAsync(conversationPair.SenderConversation);
                await _conversationRepository.UpdateAsync(conversationPair.TargetConversation);
            }
    
            try
            {
                using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: _unitOfWorkManager.Current?.Options.IsTransactional ?? false))
                {
                    foreach (var message in readMessages)
                    {
                        await _messageRepository.UpdateAsync(message);
                    }
                    await uow.CompleteAsync();
                }
            }
            catch (AbpDbConcurrencyException e)
            {
                // The messages are change by another request. So, we can ignore this exception.
            }
    
            return messages;
        }
    }
    
Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11