attempt to switch ident service to redis
This commit is contained in:
@@ -82,12 +82,12 @@ public partial class MareHub
|
||||
public async Task<List<OnlineUserDto>> AdminGetOnlineUsers()
|
||||
{
|
||||
var users = await _dbContext.Users.AsNoTracking().ToListAsync().ConfigureAwait(false);
|
||||
return users.Where(c => !string.IsNullOrEmpty(_clientIdentService.GetCharacterIdentForUid(c.UID))).Select(b => new OnlineUserDto
|
||||
return users.Select(user => new { user, GetIdentFromUidFromRedis(user.UID).Result }).Where(a => !string.IsNullOrEmpty(a.Result)).Select(b => new OnlineUserDto
|
||||
{
|
||||
CharacterNameHash = _clientIdentService.GetCharacterIdentForUid(b.UID),
|
||||
UID = b.UID,
|
||||
IsModerator = b.IsModerator,
|
||||
IsAdmin = b.IsAdmin
|
||||
CharacterNameHash = b.Result,
|
||||
UID = b.user.UID,
|
||||
IsModerator = b.user.IsModerator,
|
||||
IsAdmin = b.user.IsAdmin
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,27 @@ namespace MareSynchronosServer.Hubs;
|
||||
|
||||
public partial class MareHub
|
||||
{
|
||||
private async Task UpdateUserOnRedis()
|
||||
{
|
||||
await _redis.StringSetAsync("UID:" + UserUID, UserCharaIdent, TimeSpan.FromSeconds(60), flags: StackExchange.Redis.CommandFlags.FireAndForget).ConfigureAwait(false);
|
||||
await _redis.StringSetAsync("IDENT:" + UserCharaIdent, UserUID, TimeSpan.FromSeconds(60), flags: StackExchange.Redis.CommandFlags.FireAndForget).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task RemoveUserFromRedis()
|
||||
{
|
||||
await _redis.StringGetDeleteAsync("UID:" + UserUID).ConfigureAwait(false);
|
||||
await _redis.StringGetDeleteAsync("IDENT:" + UserCharaIdent).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<string> GetIdentFromUidFromRedis(string uid)
|
||||
{
|
||||
return await _redis.StringGetAsync("UID:" + uid).ConfigureAwait(false);
|
||||
}
|
||||
public async Task<string> GetUidFromIdentFromRedis(string ident)
|
||||
{
|
||||
return await _redis.StringGetAsync("IDENT:" + ident).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<List<PausedEntry>> GetAllPairedClientsWithPauseState(string? uid = null)
|
||||
{
|
||||
uid ??= UserUID;
|
||||
@@ -81,7 +102,7 @@ public partial class MareHub
|
||||
if (userPair.IsPausedPerGroup is PauseInfo.Unpaused) return;
|
||||
}
|
||||
|
||||
var groupUserIdent = _clientIdentService.GetCharacterIdentForUid(groupUserPair.GroupUserUID);
|
||||
var groupUserIdent = await GetIdentFromUidFromRedis(groupUserPair.GroupUserUID).ConfigureAwait(false);
|
||||
if (!string.IsNullOrEmpty(groupUserIdent))
|
||||
{
|
||||
await Clients.User(uid).Client_UserChangePairedPlayer(groupUserIdent, false).ConfigureAwait(false);
|
||||
@@ -93,7 +114,7 @@ public partial class MareHub
|
||||
{
|
||||
foreach (var pair in groupUsers)
|
||||
{
|
||||
var pairIdent = _clientIdentService.GetCharacterIdentForUid(pair.GroupUserUID);
|
||||
var pairIdent = await GetIdentFromUidFromRedis(pair.GroupUserUID).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(pairIdent)) continue;
|
||||
|
||||
var pairs = await GetAllPairedClientsWithPauseState(pair.GroupUserUID).ConfigureAwait(false);
|
||||
|
||||
@@ -232,7 +232,7 @@ public partial class MareHub
|
||||
if (userPair.IsPausedExcludingGroup(gid) is PauseInfo.Unpaused) continue;
|
||||
if (userPair.IsPausedPerGroup is PauseInfo.Paused) continue;
|
||||
|
||||
var groupUserIdent = _clientIdentService.GetCharacterIdentForUid(groupUserPair.GroupUserUID);
|
||||
var groupUserIdent = await GetIdentFromUidFromRedis(groupUserPair.GroupUserUID).ConfigureAwait(false);
|
||||
if (!string.IsNullOrEmpty(groupUserIdent))
|
||||
{
|
||||
await Clients.User(UserUID).Client_UserChangePairedPlayer(groupUserIdent, true).ConfigureAwait(false);
|
||||
@@ -403,7 +403,7 @@ public partial class MareHub
|
||||
if (userPair.IsOtherPausedForSpecificGroup(gid) is PauseInfo.Paused) continue;
|
||||
}
|
||||
|
||||
var groupUserIdent = _clientIdentService.GetCharacterIdentForUid(groupUserPair.GroupUserUID);
|
||||
var groupUserIdent = await GetIdentFromUidFromRedis(groupUserPair.GroupUserUID).ConfigureAwait(false);
|
||||
if (!string.IsNullOrEmpty(groupUserIdent))
|
||||
{
|
||||
await Clients.User(UserUID).Client_UserChangePairedPlayer(groupUserIdent, !isPaused).ConfigureAwait(false);
|
||||
@@ -437,7 +437,7 @@ public partial class MareHub
|
||||
UserUID = uid,
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var userIdent = _clientIdentService.GetCharacterIdentForUid(uid);
|
||||
var userIdent = await GetIdentFromUidFromRedis(uid).ConfigureAwait(false);
|
||||
if (userIdent == null) return;
|
||||
|
||||
await Clients.User(uid).Client_GroupChange(new GroupDto()
|
||||
@@ -683,7 +683,7 @@ public partial class MareHub
|
||||
UserUID = pair.GroupUserUID
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var pairIdent = _clientIdentService.GetCharacterIdentForUid(pair.GroupUserUID);
|
||||
var pairIdent = await GetIdentFromUidFromRedis(pair.GroupUserUID).ConfigureAwait(false);
|
||||
if (string.IsNullOrEmpty(pairIdent)) continue;
|
||||
|
||||
var allUserPairs = await GetAllPairedClientsWithPauseState(pair.GroupUserUID).ConfigureAwait(false);
|
||||
|
||||
@@ -64,7 +64,7 @@ public partial class MareHub
|
||||
_logger.LogCallInfo();
|
||||
|
||||
var usersToSendOnlineTo = await SendOnlineToAllPairedUsers(UserCharaIdent).ConfigureAwait(false);
|
||||
return usersToSendOnlineTo.Select(e => _clientIdentService.GetCharacterIdentForUid(e)).Where(t => !string.IsNullOrEmpty(t)).Distinct(StringComparer.Ordinal).ToList();
|
||||
return usersToSendOnlineTo.Select(e => GetIdentFromUidFromRedis(e).Result).Where(t => !string.IsNullOrEmpty(t)).Distinct(StringComparer.Ordinal).ToList();
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
@@ -147,7 +147,7 @@ public partial class MareHub
|
||||
|
||||
var allPairedUsers = await GetAllPairedUnpausedUsers().ConfigureAwait(false);
|
||||
|
||||
var allPairedUsersDict = allPairedUsers.ToDictionary(f => f, f => _clientIdentService.GetCharacterIdentForUid(f), StringComparer.Ordinal)
|
||||
var allPairedUsersDict = allPairedUsers.ToDictionary(f => f, f => GetIdentFromUidFromRedis(f).Result, StringComparer.Ordinal)
|
||||
.Where(f => visibleCharacterIds.Contains(f.Value, StringComparer.Ordinal));
|
||||
|
||||
_logger.LogCallInfo(MareHubLogger.Args(visibleCharacterIds.Count, allPairedUsersDict.Count()));
|
||||
@@ -209,7 +209,7 @@ public partial class MareHub
|
||||
if (otherEntry == null) return;
|
||||
|
||||
// check if other user is online
|
||||
var otherIdent = _clientIdentService.GetCharacterIdentForUid(otherUser.UID);
|
||||
var otherIdent = await GetIdentFromUidFromRedis(otherUser.UID).ConfigureAwait(false);
|
||||
if (otherIdent == null) return;
|
||||
|
||||
// send push with update to other user if other user is online
|
||||
@@ -224,7 +224,7 @@ public partial class MareHub
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
// get own ident and all pairs
|
||||
var userIdent = _clientIdentService.GetCharacterIdentForUid(user.UID);
|
||||
var userIdent = await GetIdentFromUidFromRedis(user.UID).ConfigureAwait(false);
|
||||
var allUserPairs = await GetAllPairedClientsWithPauseState().ConfigureAwait(false);
|
||||
|
||||
// if the other user has paused the main user and there was no previous group connection don't send anything
|
||||
@@ -270,7 +270,7 @@ public partial class MareHub
|
||||
IsSynced = true
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var otherCharaIdent = _clientIdentService.GetCharacterIdentForUid(pair.OtherUserUID);
|
||||
var otherCharaIdent = await GetIdentFromUidFromRedis(pair.OtherUserUID).ConfigureAwait(false);
|
||||
|
||||
if (UserCharaIdent == null || otherCharaIdent == null || otherEntry.IsPaused) return;
|
||||
|
||||
@@ -310,7 +310,7 @@ public partial class MareHub
|
||||
if (oppositeClientPair == null) return;
|
||||
|
||||
// check if other user is online, if no then there is no need to do anything further
|
||||
var otherIdent = _clientIdentService.GetCharacterIdentForUid(otherUserUid);
|
||||
var otherIdent = await GetIdentFromUidFromRedis(otherUserUid).ConfigureAwait(false);
|
||||
if (otherIdent == null) return;
|
||||
|
||||
// get own ident and
|
||||
|
||||
@@ -9,6 +9,7 @@ using MareSynchronosShared.Services;
|
||||
using MareSynchronosShared.Utils;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace MareSynchronosServer.Hubs;
|
||||
|
||||
@@ -19,7 +20,6 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
||||
private readonly FileService.FileServiceClient _fileServiceClient;
|
||||
private readonly SystemInfoService _systemInfoService;
|
||||
private readonly IHttpContextAccessor _contextAccessor;
|
||||
private readonly IClientIdentificationService _clientIdentService;
|
||||
private readonly MareHubLogger _logger;
|
||||
private readonly MareDbContext _dbContext;
|
||||
private readonly Uri _mainCdnFullUrl;
|
||||
@@ -28,11 +28,12 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
||||
private readonly int _maxJoinedGroupsByUser;
|
||||
private readonly int _maxGroupUserCount;
|
||||
private readonly IConfigurationService<ServerConfiguration> _configurationService;
|
||||
private readonly IDatabase _redis;
|
||||
|
||||
public MareHub(MareMetrics mareMetrics, FileService.FileServiceClient fileServiceClient,
|
||||
MareDbContext mareDbContext, ILogger<MareHub> logger, SystemInfoService systemInfoService,
|
||||
IConfigurationService<ServerConfiguration> configuration, IHttpContextAccessor contextAccessor,
|
||||
IClientIdentificationService clientIdentService)
|
||||
IConnectionMultiplexer connectionMultiplexer)
|
||||
{
|
||||
_mareMetrics = mareMetrics;
|
||||
_fileServiceClient = fileServiceClient;
|
||||
@@ -44,7 +45,7 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
||||
_maxJoinedGroupsByUser = configuration.GetValueOrDefault(nameof(ServerConfiguration.MaxJoinedGroupsByUser), 6);
|
||||
_maxGroupUserCount = configuration.GetValueOrDefault(nameof(ServerConfiguration.MaxGroupUserCount), 100);
|
||||
_contextAccessor = contextAccessor;
|
||||
_clientIdentService = clientIdentService;
|
||||
_redis = connectionMultiplexer.GetDatabase();
|
||||
_logger = new MareHubLogger(this, logger);
|
||||
_dbContext = mareDbContext;
|
||||
}
|
||||
@@ -92,14 +93,9 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
||||
[Authorize(Policy = "Authenticated")]
|
||||
public async Task<bool> CheckClientHealth()
|
||||
{
|
||||
var needsReconnect = !_clientIdentService.IsOnCurrentServer(UserUID);
|
||||
if (needsReconnect)
|
||||
{
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Warning, "Internal server state corruption detected, reconnecting you automatically to fix the issue.").ConfigureAwait(false);
|
||||
_logger.LogCallWarning(MareHubLogger.Args(needsReconnect));
|
||||
}
|
||||
await UpdateUserOnRedis().ConfigureAwait(false);
|
||||
|
||||
return needsReconnect;
|
||||
return false;
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Authenticated")]
|
||||
@@ -111,7 +107,7 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
||||
{
|
||||
_logger.LogCallInfo(MareHubLogger.Args(_contextAccessor.GetIpAddress(), UserCharaIdent));
|
||||
|
||||
_clientIdentService.MarkUserOnline(UserUID, UserCharaIdent);
|
||||
await UpdateUserOnRedis().ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
|
||||
@@ -127,7 +123,7 @@ public partial class MareHub : Hub<IMareHub>, IMareHub
|
||||
{
|
||||
_logger.LogCallInfo(MareHubLogger.Args(_contextAccessor.GetIpAddress(), UserCharaIdent));
|
||||
|
||||
_clientIdentService.MarkUserOffline(UserUID);
|
||||
await RemoveUserFromRedis().ConfigureAwait(false);
|
||||
|
||||
await SendOfflineToAllPairedUsers(UserCharaIdent).ConfigureAwait(false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user