Optimise disconnect logic

Instead of trying to prevent stale connections, we just let the code remove them from existence. If they no longer exist, they'll get an error and reconnect.
This commit is contained in:
2025-09-04 19:29:23 -04:00
parent 74155ce171
commit 271a6b0373

View File

@@ -81,7 +81,7 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
await DbContext.SaveChangesAsync().ConfigureAwait(false); await DbContext.SaveChangesAsync().ConfigureAwait(false);
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Information, "Welcome to Snowcloak! Current Online Users: " + _systemInfoService.SystemInfoDto.OnlineUsers).ConfigureAwait(false); await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Information, "Welcome to Snowcloak! Current Online Users: " + _systemInfoService.SystemInfoDto.OnlineUsers).ConfigureAwait(false);
Context.Items["IsClientConnected"] = true;
return new ConnectionDto(new UserData(dbUser.UID, string.IsNullOrWhiteSpace(dbUser.Alias) ? null : dbUser.Alias)) return new ConnectionDto(new UserData(dbUser.UID, string.IsNullOrWhiteSpace(dbUser.Alias) ? null : dbUser.Alias))
{ {
CurrentClientVersion = _expectedClientVersion, CurrentClientVersion = _expectedClientVersion,
@@ -103,15 +103,16 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
[Authorize(Policy = "Authenticated")] [Authorize(Policy = "Authenticated")]
public async Task<bool> CheckClientHealth() public async Task<bool> CheckClientHealth()
{ {
try // Key missing -> health check failed!
{ var exists = await _redis.ExistsAsync("UID:" + UserUID).ConfigureAwait(false);
await UpdateUserOnRedis().ConfigureAwait(false); if (!exists)
return true;
}
catch
{ {
return false; return false;
} }
// Key exists -> health is good!
await UpdateUserOnRedis().ConfigureAwait(false);
return true;
} }
[Authorize(Policy = "Authenticated")] [Authorize(Policy = "Authenticated")]
@@ -121,8 +122,7 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
try try
{ {
_logger.LogCallInfo(MareHubLogger.Args(_contextAccessor.GetIpAddress(), UserCharaIdent)); _logger.LogCallInfo(MareHubLogger.Args("A client reconnected.", _contextAccessor.GetIpAddress(), UserCharaIdent));
await UpdateUserOnRedis().ConfigureAwait(false); await UpdateUserOnRedis().ConfigureAwait(false);
} }
catch { } catch { }
@@ -133,24 +133,16 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
[Authorize(Policy = "Authenticated")] [Authorize(Policy = "Authenticated")]
public override async Task OnDisconnectedAsync(Exception exception) public override async Task OnDisconnectedAsync(Exception exception)
{ {
DateTime _lastdc = DateTime.UtcNow;
_mareMetrics.DecGaugeWithLabels(MetricsAPI.GaugeConnections, labels: Continent); _mareMetrics.DecGaugeWithLabels(MetricsAPI.GaugeConnections, labels: Continent);
try try
{ {
// Check DB to see if the user reconnected after this disconnect
await Task.Delay(TimeSpan.FromSeconds(3)).ConfigureAwait(false);
var dbUser = await DbContext.Users.AsNoTracking().SingleOrDefaultAsync(u => u.UID == UserUID).ConfigureAwait(false);
if (dbUser != null && dbUser.LastLoggedIn < _lastdc)
{
_logger.LogCallInfo(MareHubLogger.Args(_contextAccessor.GetIpAddress(), UserCharaIdent)); _logger.LogCallInfo(MareHubLogger.Args(_contextAccessor.GetIpAddress(), UserCharaIdent));
if (exception != null) if (exception != null)
_logger.LogCallWarning(MareHubLogger.Args(_contextAccessor.GetIpAddress(), exception.Message, exception.StackTrace)); _logger.LogCallWarning(MareHubLogger.Args(_contextAccessor.GetIpAddress(), exception.Message, exception.StackTrace));
await GposeLobbyLeave().ConfigureAwait(false); await GposeLobbyLeave().ConfigureAwait(false);
await RemoveUserFromRedis().ConfigureAwait(false); await RemoveUserFromRedis().ConfigureAwait(false);
await SendOfflineToAllPairedUsers().ConfigureAwait(false); await SendOfflineToAllPairedUsers().ConfigureAwait(false);
}
} }
catch { } catch { }