网页版推演服务器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
5.6 KiB

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<FireDeductionHub> _logger;
public FireDeductionHub(
ApplicationDbContext dbContext,
ILogger<FireDeductionHub> logger,
RoomManager roomManager)
{
_dbContext = dbContext;
_logger = logger;
this.roomManager = roomManager;
}
public async Task<FireDeductionRoom> 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<bool> 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<bool> 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;
}
}
}
}