IM/backend/IM_API/Application/EventHandlers/ConversationEventHandler.cs

89 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AutoMapper;
using IM_API.Application.Interfaces;
using IM_API.Domain.Events;
using IM_API.Dtos;
using IM_API.Exceptions;
using IM_API.Interface.Services;
using IM_API.Models;
using IM_API.Services;
using IM_API.Tools;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
namespace IM_API.Application.EventHandlers
{
public class ConversationEventHandler : IEventHandler<MessageCreatedEvent>
{
private readonly IConversationService _conversationService;
private readonly ILogger<ConversationEventHandler> _logger;
private readonly ImContext _context;
private readonly IMapper _mapper;
public ConversationEventHandler(
IConversationService conversationService,
ILogger<ConversationEventHandler> logger,
ImContext imContext,
IMapper mapper
)
{
_conversationService = conversationService;
_logger = logger;
_context = imContext;
_mapper = mapper;
}
/*
* 此方法有并发问题,当双方同时第一次发送消息时,
* 会出现同时创建的情况,其中一方会报错,
* 导致也未走到更新逻辑,会话丢失
*/
public async Task Handle(MessageCreatedEvent @event)
{
//此处仅处理私聊会话创建
if (@event.ChatType == ChatType.GROUP)
{
return;
}
var conversation = await _context.Conversations.FirstOrDefaultAsync(
x => x.UserId == @event.MsgSenderId && x.TargetId == @event.MsgRecipientId
);
//如果首次发消息则创建双方会话
if (conversation is null)
{
Conversation senderCon = _mapper.Map<Conversation>(@event);
Conversation ReceptCon = _mapper.Map<Conversation>(@event);
ReceptCon.UserId = @event.MsgRecipientId;
ReceptCon.TargetId = @event.MsgSenderId;
ReceptCon.UnreadCount += 1;
ReceptCon.LastReadMessageId = null;
_context.Conversations.AddRange(senderCon,ReceptCon);
await _context.SaveChangesAsync();
}
else
{
Conversation senderCon = conversation;
Conversation? ReceptCon = await _context.Conversations.FirstOrDefaultAsync(
x => x.UserId == @event.MsgRecipientId && x.TargetId == @event.MsgSenderId);
if (ReceptCon is null)
{
_logger.LogError("ConversationEventHandlerError接收者会话对象缺失Event:{Event}", JsonConvert.SerializeObject(@event));
throw new BaseException(CodeDefine.SYSTEM_ERROR);
}
//更新发送者conversation
senderCon.UnreadCount = 0;
senderCon.LastReadMessageId = @event.MessageId;
senderCon.LastMessage = @event.MessageContent;
senderCon.LastMessageTime = DateTime.Now;
//更新接收者conversation
ReceptCon.UnreadCount += 1;
ReceptCon.LastMessage = @event.MessageContent;
senderCon.LastMessageTime = DateTime.Now;
_context.Conversations.UpdateRange(senderCon, ReceptCon);
await _context.SaveChangesAsync();
}
}
}
}