using AutoMapper; using IM_API.Application.Interfaces; using IM_API.Domain.Events; using IM_API.Dtos; using IM_API.Interface.Services; using IM_API.Models; using IM_API.Tools; using IM_API.VOs.Message; using Microsoft.AspNetCore.SignalR; using StackExchange.Redis; using System.Security.Claims; namespace IM_API.Hubs { public class ChatHub:Hub { private IMessageSevice _messageService; private readonly IConversationService _conversationService; private readonly IDatabase _redis; public ChatHub(IMessageSevice messageService, IConversationService conversationService, IConnectionMultiplexer connectionMultiplexer) { _messageService = messageService; _conversationService = conversationService; _redis = connectionMultiplexer.GetDatabase(); } public async override Task OnConnectedAsync() { if (!Context.User.Identity.IsAuthenticated) { Context.Abort(); return; } //将用户加入已加入聊天的会话组 string userIdStr = Context.User.FindFirstValue(ClaimTypes.NameIdentifier); var keys = await _conversationService.GetUserAllStreamKeyAsync(int.Parse(userIdStr)); foreach (var key in keys) { await Groups.AddToGroupAsync(Context.ConnectionId, key); } //储存用户对应的连接id await _redis.SetAddAsync(RedisKeys.GetConnectionIdKey(userIdStr), Context.ConnectionId); await base.OnConnectedAsync(); } public override async Task OnDisconnectedAsync(Exception? exception) { if (!Context.User.Identity.IsAuthenticated) { string useridStr = Context.User.FindFirstValue(ClaimTypes.NameIdentifier); await _redis.SetRemoveAsync(RedisKeys.GetConnectionIdKey(useridStr), Context.ConnectionId); } await base.OnDisconnectedAsync(exception); } public async Task> SendMessage(MessageBaseDto dto) { if (!Context.User.Identity.IsAuthenticated) { await Clients.Caller.SendAsync("ReceiveMessage", new BaseResponse(CodeDefine.AUTH_FAILED)); Context.Abort(); return new HubResponse(CodeDefine.AUTH_FAILED, "SendMessage"); } var userIdStr = Context.User.FindFirstValue(ClaimTypes.NameIdentifier); MessageBaseVo? msgInfo = null; if(dto.ChatType == ChatType.PRIVATE) { msgInfo = await _messageService.SendPrivateMessageAsync(int.Parse(userIdStr), dto.ReceiverId, dto); } else { msgInfo = await _messageService.SendGroupMessageAsync(int.Parse(userIdStr), dto.ReceiverId, dto); } return new HubResponse("SendMessage", msgInfo); } public async Task> ClearUnreadCount(int conversationId) { if (!Context.User.Identity.IsAuthenticated) { await Clients.Caller.SendAsync("ReceiveMessage", new BaseResponse(CodeDefine.AUTH_FAILED)); Context.Abort(); return new HubResponse(CodeDefine.AUTH_FAILED, "ClearUnreadCount"); ; } var userIdStr = Context.User.FindFirstValue(ClaimTypes.NameIdentifier); await _conversationService.ClearUnreadCountAsync(int.Parse(userIdStr), conversationId); return new HubResponse("ClearUnreadCount"); } } }