using AX.WebDrillServer.Data; using AX.WebDrillServer.Extensions; using AX.WebDrillServer.Middlewares.Jwts; using AX.WebDrillServer.Models; using AX.WebDrillServer.Services.FireDeductionHub; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Memory; using System.Collections.Concurrent; using System.Security.Claims; namespace AX.WebDrillServer.Hubs { //[Authorize] public class FireDeductionHub : Hub { private readonly RoomManager roomManager; private readonly ApplicationDbContext _dbContext; private readonly ILogger _logger; public FireDeductionHub( ApplicationDbContext dbContext, ILogger logger, RoomManager roomManager) { _dbContext = dbContext; _logger = logger; this.roomManager = roomManager; } public async Task CreateRoom(RoomCreateDto createInfo, FireDeductionUser user) { FireDeductionRoom room = new FireDeductionRoom(); room.Owner = createInfo.UserId; room.RoomId = Guid.NewGuid().ToString(); room.RoomName = createInfo.RoomName; room.Password = createInfo.RoomPassword; room.Users.Add(user); await Groups.AddToGroupAsync(user.ConnectionId, room.RoomId); return room; } public async Task EnterRoom(string roomId, FireDeductionUser user, string? password = null) { bool result = false; var room = roomManager.GetRoom(roomId); if (room != null && room.Password == password) { if (!room.Users.Contains(user)) { result = true; } else { throw new NotImplementedException("房间中已经存在该用户!"); } } else { throw new NotImplementedException("房间信息有误!"); } return result; } public async Task LeaveRoom(string roomId, string userId) { bool result = false; await Task.Run(() => { var room = roomManager.GetRoom(roomId); if (room != null) { var user = room.Users.FirstOrDefault(u => u.UserId == userId); if (user != null) { room.Users.Remove(user); if (room.Users.Count == 0) { //TODO:保持空房间xx分钟 } } else { throw new NotImplementedException("用户信息有误!"); } } else { throw new NotImplementedException("房间信息有误!"); } }); return result; } public async Task RoomSendMessage(string RoomId, string Message) { await Clients.Group(RoomId).SendAsync(Message); //TODO:保存数据 } public async Task SendMessage(string user, string Message) { await Clients.All.SendAsync(Message); //TODO:保存数据 } public override async Task OnConnectedAsync() { try { var userId = Context.UserIdentifier; var userName = Context.GetNameOfCurrentUser(); FireDeductionUser? user = roomManager.GetUser(userId!); if (user != null) { user.Online = true; var room = roomManager.GetRoomByUserId(user.UserId); if (room != null) { //断线重连 } } else { user = new FireDeductionUser(); user.ConnectionId = Context.ConnectionId; user.UserId = userId!; user.UserName = userName!; } _logger.LogInformation("[{userId}][{name}] connected", userId, userName); await base.OnConnectedAsync(); } catch (Exception) { throw; } } public override async Task OnDisconnectedAsync(Exception? exception) { try { var userId = Context.UserIdentifier; var userName = Context.User?.FindFirstValue(JwtClaimTypes.Name); if (userId == null) _logger.LogError("无效的 userId: [{userId}]!", userId); if (userId != null) { var user = roomManager.GetUser(userId!); if (user != null) { user.Online = false; var room = roomManager.GetRoomByUserId(user.UserId); if (room != null) { //断线 } } } await base.OnDisconnectedAsync(exception); _logger.LogInformation("[{userId}][{name}] 断开了连接", userId, userName); } catch (Exception) { throw; } } } }