Rework Online User Tracking

This commit is contained in:
Alan Moon 2025-07-12 10:50:36 -07:00
parent 4cdedab2c1
commit bdbd00bb2a

View File

@ -8,10 +8,10 @@ namespace qtc_api.Hubs
private IUserService _userService; private IUserService _userService;
private IRoomService _roomService; private IRoomService _roomService;
private ILogger<ChatHub> _logger; private ILogger<ChatHub> _logger;
private static List<UserConnectionDto> ConnectedUsers = new();
private static List<User> OnlineUsers = new();
private static Dictionary<string, List<User>> GroupUsers = new(); private static readonly Dictionary<string, List<User>> GroupUsers = [];
private static readonly Dictionary<string, List<string>> ConnectedUsers = [];
private static readonly List<User> OnlineUsers = [];
public ChatHub(IUserService userService, IRoomService roomService, ILogger<ChatHub> logger) public ChatHub(IUserService userService, IRoomService roomService, ILogger<ChatHub> logger)
{ {
@ -20,25 +20,6 @@ namespace qtc_api.Hubs
_logger = logger; _logger = logger;
} }
public override async Task OnDisconnectedAsync(Exception? ex)
{
Log("Client Disconnected From Hub");
var connection = ConnectedUsers.FirstOrDefault(x => x.ConnectionId == Context.ConnectionId);
if (connection != null)
{
var user = OnlineUsers.FirstOrDefault(x => x.Id == connection.ConnectedUser!.Id);
if (user != null)
{
ConnectedUsers.Remove(connection);
OnlineUsers.Remove(user);
await LogoutAsync(user);
}
}
}
public async override Task OnConnectedAsync() public async override Task OnConnectedAsync()
{ {
Log("Client Connected To Hub"); Log("Client Connected To Hub");
@ -49,10 +30,61 @@ namespace qtc_api.Hubs
var user = await _userService.GetUserById(uid); var user = await _userService.GetUserById(uid);
if (user != null && user.Success && user.Data != null) if (user != null && user.Success && user.Data != null)
{ {
// log them in var userId = user.Data.Id;
ConnectedUsers.Add(new UserConnectionDto() { ConnectedUser = user.Data, ConnectionId = Context.ConnectionId });
OnlineUsers.Add(user.Data); lock (ConnectedUsers)
await LoginAsync(user.Data); {
if(!ConnectedUsers.TryGetValue(userId, out List<string>? value))
{
value = [];
ConnectedUsers[userId] = value;
}
value.Add(Context.ConnectionId);
}
if(!OnlineUsers.Any(e => e.Id == userId))
{
OnlineUsers.Add(user.Data);
await LoginAsync(user.Data);
}
}
}
}
public override async Task OnDisconnectedAsync(Exception? ex)
{
Log("Client Disconnected From Hub");
var uid = Context.UserIdentifier;
if (uid != null)
{
var user = await _userService.GetUserById(uid);
if (user != null && user.Success && user.Data != null)
{
var userId = user.Data.Id;
lock (ConnectedUsers)
{
if(ConnectedUsers.TryGetValue(userId, out List<string>? value))
{
value.Remove(Context.ConnectionId);
}
}
if (ConnectedUsers[userId].Count == 0)
{
ConnectedUsers.Remove(userId);
if (OnlineUsers.Any(e => e.Id == userId))
{
var onlineUser = OnlineUsers.FirstOrDefault(e => e.Id == userId);
if(onlineUser != null)
{
OnlineUsers.Remove(onlineUser);
await LogoutAsync(onlineUser);
}
}
}
} }
} }
} }
@ -155,12 +187,15 @@ namespace qtc_api.Hubs
public async Task SendDirectMessageAsync(User user, UserInformationDto userToMsg, Message message) public async Task SendDirectMessageAsync(User user, UserInformationDto userToMsg, Message message)
{ {
// send direct message directly to connected user // send direct message directly to connected user
var connection = ConnectedUsers.FirstOrDefault(e => e.ConnectedUser.Id == userToMsg.Id); if(ConnectedUsers.TryGetValue(userToMsg.Id, out List<string>? value))
if (connection != null)
{ {
UserInformationDto userInformationDto = new UserInformationDto { Id = user.Id, Username = user.Username, Bio = user.Bio, Role = user.Role, Status = user.Status, CreatedAt = user.CreatedAt, DateOfBirth = user.DateOfBirth, ProfilePicture = user.ProfilePicture }; var connection = value.FirstOrDefault();
await Clients.Client(connection.ConnectionId).SendAsync("ReceiveDirectMessage", message, userInformationDto); if(connection != null)
return; {
UserInformationDto userInformationDto = new UserInformationDto { Id = user.Id, Username = user.Username, Bio = user.Bio, Role = user.Role, Status = user.Status, CreatedAt = user.CreatedAt, DateOfBirth = user.DateOfBirth, ProfilePicture = user.ProfilePicture };
await Clients.Client(connection).SendAsync("ReceiveDirectMessage", message, userInformationDto);
return;
}
} }
} }