diff --git a/Docker/run/compose/mare-standalone.yml b/Docker/run/compose/mare-standalone.yml index b3914ac..eaf02a6 100644 --- a/Docker/run/compose/mare-standalone.yml +++ b/Docker/run/compose/mare-standalone.yml @@ -15,6 +15,12 @@ services: timeout: 5s retries: 5 + redis: + image: redis:latest + command: [sh, -c, "rm -f /data/dump.rdb && redis-server --save \"\" --appendonly no --requirepass secretredispassword"] + volumes: + - cache:/data + mare-server: image: darkarchon/mare-synchronos-server:latest restart: on-failure diff --git a/Docker/run/config/standalone/server-standalone.json b/Docker/run/config/standalone/server-standalone.json index d154f8f..eae27a9 100644 --- a/Docker/run/config/standalone/server-standalone.json +++ b/Docker/run/config/standalone/server-standalone.json @@ -35,7 +35,7 @@ "WhitelistedIps": [ "" ], - "RedisConnectionString": "", + "RedisConnectionString": "redis,password=secretredispassword", "CdnFullUrl": "http://localhost:6200/cache/", "StaticFileServiceAddress": "http://mare-files:6205", "MaxExistingGroupsByUser": 3, diff --git a/Docker/run/config/standalone/services-standalone.json b/Docker/run/config/standalone/services-standalone.json index 323d015..c943a86 100644 --- a/Docker/run/config/standalone/services-standalone.json +++ b/Docker/run/config/standalone/services-standalone.json @@ -29,7 +29,8 @@ "ShardName": "Services", "MetricsPort": 6150, "MainServerGrpcAddress": "http://mare-server:6005", - "DiscordBotToken": "" + "DiscordBotToken": "", + "RedisConnectionString": "redis,password=secretredispassword" }, "AllowedHosts": "*", "Kestrel": { diff --git a/MareSynchronosServer/MareSynchronosServer/Controllers/JwtController.cs b/MareSynchronosServer/MareSynchronosServer/Controllers/JwtController.cs index 1a75200..e303e76 100644 --- a/MareSynchronosServer/MareSynchronosServer/Controllers/JwtController.cs +++ b/MareSynchronosServer/MareSynchronosServer/Controllers/JwtController.cs @@ -1,6 +1,5 @@ using MareSynchronos.API; using MareSynchronosServer.Authentication; -using MareSynchronosServer.Services; using MareSynchronosShared; using MareSynchronosShared.Data; using MareSynchronosShared.Services; @@ -9,6 +8,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; +using StackExchange.Redis; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; @@ -20,21 +20,21 @@ namespace MareSynchronosServer.Controllers; public class JwtController : Controller { private readonly IHttpContextAccessor _accessor; + private readonly IDatabase _redis; private readonly MareDbContext _mareDbContext; private readonly SecretKeyAuthenticatorService _secretKeyAuthenticatorService; private readonly IConfigurationService _configuration; - private readonly IClientIdentificationService _clientIdentService; public JwtController(IHttpContextAccessor accessor, MareDbContext mareDbContext, SecretKeyAuthenticatorService secretKeyAuthenticatorService, IConfigurationService configuration, - IClientIdentificationService clientIdentService) + IConnectionMultiplexer connectionMultiplexer) { _accessor = accessor; + _redis = connectionMultiplexer.GetDatabase(); _mareDbContext = mareDbContext; _secretKeyAuthenticatorService = secretKeyAuthenticatorService; _configuration = configuration; - _clientIdentService = clientIdentService; } [AllowAnonymous] @@ -54,7 +54,7 @@ public class JwtController : Controller if (!authResult.Success && !authResult.TempBan) return Unauthorized("The provided secret key is invalid. Verify your accounts existence and/or recover the secret key."); if (!authResult.Success && authResult.TempBan) return Unauthorized("You are temporarily banned. Try connecting again later."); - var existingIdent = _clientIdentService.GetCharacterIdentForUid(authResult.Uid); + var existingIdent = await _redis.StringGetAsync("UID:" + authResult.Uid); if (!string.IsNullOrEmpty(existingIdent)) return Unauthorized("Already logged in to this account."); var token = CreateToken(new List() diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Admin.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Admin.cs index f58ac69..0092739 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Admin.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Admin.cs @@ -82,12 +82,12 @@ public partial class MareHub public async Task> 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(); } diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs index 7b31343..e84e893 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Functions.cs @@ -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 GetIdentFromUidFromRedis(string uid) + { + return await _redis.StringGetAsync("UID:" + uid).ConfigureAwait(false); + } + public async Task GetUidFromIdentFromRedis(string ident) + { + return await _redis.StringGetAsync("IDENT:" + ident).ConfigureAwait(false); + } + private async Task> 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); diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs index 02f1f96..af7b499 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.Groups.cs @@ -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); diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs index eb622a3..54b534d 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.User.cs @@ -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 diff --git a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs index 9900ea8..72fa4ee 100644 --- a/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs +++ b/MareSynchronosServer/MareSynchronosServer/Hubs/MareHub.cs @@ -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 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 private readonly int _maxJoinedGroupsByUser; private readonly int _maxGroupUserCount; private readonly IConfigurationService _configurationService; + private readonly IDatabase _redis; public MareHub(MareMetrics mareMetrics, FileService.FileServiceClient fileServiceClient, MareDbContext mareDbContext, ILogger logger, SystemInfoService systemInfoService, IConfigurationService configuration, IHttpContextAccessor contextAccessor, - IClientIdentificationService clientIdentService) + IConnectionMultiplexer connectionMultiplexer) { _mareMetrics = mareMetrics; _fileServiceClient = fileServiceClient; @@ -44,7 +45,7 @@ public partial class MareHub : Hub, 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 [Authorize(Policy = "Authenticated")] public async Task 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 { _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 { _logger.LogCallInfo(MareHubLogger.Args(_contextAccessor.GetIpAddress(), UserCharaIdent)); - _clientIdentService.MarkUserOffline(UserUID); + await RemoveUserFromRedis().ConfigureAwait(false); await SendOfflineToAllPairedUsers(UserCharaIdent).ConfigureAwait(false); diff --git a/MareSynchronosServer/MareSynchronosServer/Identity/IdentityHandler.cs b/MareSynchronosServer/MareSynchronosServer/Identity/IdentityHandler.cs deleted file mode 100644 index 9103fdb..0000000 --- a/MareSynchronosServer/MareSynchronosServer/Identity/IdentityHandler.cs +++ /dev/null @@ -1,98 +0,0 @@ -using MareSynchronosShared.Protos; -using System.Collections.Concurrent; - -namespace MareSynchronosServer.Identity; - -public class IdentityHandler -{ - private readonly ConcurrentDictionary _cachedIdentities = new(StringComparer.Ordinal); - private readonly ConcurrentDictionary> _identChanges = new(StringComparer.Ordinal); - private readonly ILogger _logger; - - public IdentityHandler(ILogger logger) - { - _logger = logger; - } - - internal Task GetIdentForUid(string uid) - { - if (!_cachedIdentities.TryGetValue(uid, out ServerIdentity result)) - { - result = new ServerIdentity(); - } - - return Task.FromResult(result); - } - - internal void SetIdent(string uid, string serverId, string ident) - { - _cachedIdentities[uid] = new ServerIdentity() { ServerId = serverId, CharacterIdent = ident }; - } - - internal void RemoveIdent(string uid, string serverId) - { - if (_cachedIdentities.ContainsKey(uid) && string.Equals(_cachedIdentities[uid].ServerId, serverId, StringComparison.Ordinal)) - { - _cachedIdentities.TryRemove(uid, out _); - } - } - - internal int GetOnlineUsers(string serverId) - { - if (string.IsNullOrEmpty(serverId)) - return _cachedIdentities.Count; - return _cachedIdentities.Count(c => string.Equals(c.Value.ServerId, serverId, StringComparison.Ordinal)); - } - - internal Dictionary GetIdentsForAllExcept(string serverId) - { - return _cachedIdentities.Where(k => !string.Equals(k.Value.ServerId, serverId, StringComparison.Ordinal)).ToDictionary(k => k.Key, k => k.Value, StringComparer.Ordinal); - } - - internal Dictionary GetIdentsForServer(string serverId) - { - return _cachedIdentities.Where(k => string.Equals(k.Value.ServerId, serverId, StringComparison.Ordinal)).ToDictionary(k => k.Key, k => k.Value, StringComparer.Ordinal); - } - - internal void ClearIdentsForServer(string serverId) - { - var serverIdentities = _cachedIdentities.Where(i => string.Equals(i.Value.ServerId, serverId, StringComparison.Ordinal)); - foreach (var identity in serverIdentities) - { - _cachedIdentities.TryRemove(identity.Key, out _); - } - } - - internal void EnqueueIdentChange(IdentChange identchange) - { - _logger.LogDebug("Enqueued " + identchange.UidWithIdent.Uid.Uid + ":" + identchange.IsOnline + " from " + identchange.UidWithIdent.Ident.ServerId); - - foreach (var k in _identChanges.Keys) - { - if (string.Equals(k, identchange.UidWithIdent.Ident.ServerId, StringComparison.Ordinal)) continue; - _identChanges[k].Enqueue(identchange); - } - } - - internal bool DequeueIdentChange(string server, out IdentChange cur) - { - if (!(_identChanges.ContainsKey(server) && _identChanges[server].TryDequeue(out cur))) - { - cur = null; - return false; - } - - return true; - } - - internal void RegisterServerForQueue(string serverId) - { - _identChanges[serverId] = new ConcurrentQueue(); - } - - internal record ServerIdentity - { - public string ServerId { get; set; } = string.Empty; - public string CharacterIdent { get; set; } = string.Empty; - } -} diff --git a/MareSynchronosServer/MareSynchronosServer/MareSynchronosServer.csproj b/MareSynchronosServer/MareSynchronosServer/MareSynchronosServer.csproj index a24a34d..9edaa8e 100644 --- a/MareSynchronosServer/MareSynchronosServer/MareSynchronosServer.csproj +++ b/MareSynchronosServer/MareSynchronosServer/MareSynchronosServer.csproj @@ -38,6 +38,7 @@ + @@ -46,4 +47,8 @@ + + + + diff --git a/MareSynchronosServer/MareSynchronosServer/RequirementHandlers/UserRequirementHandler.cs b/MareSynchronosServer/MareSynchronosServer/RequirementHandlers/UserRequirementHandler.cs index 4acec83..4e09caf 100644 --- a/MareSynchronosServer/MareSynchronosServer/RequirementHandlers/UserRequirementHandler.cs +++ b/MareSynchronosServer/MareSynchronosServer/RequirementHandlers/UserRequirementHandler.cs @@ -2,22 +2,22 @@ using Microsoft.AspNetCore.SignalR; using MareSynchronosShared.Data; using Microsoft.EntityFrameworkCore; -using MareSynchronosServer.Services; using MareSynchronosShared.Utils; +using StackExchange.Redis; namespace MareSynchronosServer.RequirementHandlers; public class UserRequirementHandler : AuthorizationHandler { - private readonly IClientIdentificationService identClient; - private readonly MareDbContext dbContext; - private readonly ILogger logger; + private readonly MareDbContext _dbContext; + private readonly ILogger _logger; + private readonly IDatabase _redis; - public UserRequirementHandler(IClientIdentificationService identClient, MareDbContext dbContext, ILogger logger) + public UserRequirementHandler(MareDbContext dbContext, ILogger logger, IConnectionMultiplexer connectionMultiplexer) { - this.identClient = identClient; - this.dbContext = dbContext; - this.logger = logger; + _dbContext = dbContext; + _logger = logger; + _redis = connectionMultiplexer.GetDatabase(); } protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, UserRequirement requirement, HubInvocationContext resource) @@ -28,25 +28,22 @@ public class UserRequirementHandler : AuthorizationHandler b.UID == uid).ConfigureAwait(false); + var user = await _dbContext.Users.AsNoTracking().SingleOrDefaultAsync(b => b.UID == uid).ConfigureAwait(false); if (user == null || !user.IsAdmin) context.Fail(); - logger.LogInformation("Admin {uid} authenticated", uid); + _logger.LogInformation("Admin {uid} authenticated", uid); } if ((requirement.Requirements & UserRequirements.Moderator) is UserRequirements.Moderator) { - var user = await dbContext.Users.AsNoTracking().SingleOrDefaultAsync(b => b.UID == uid).ConfigureAwait(false); + var user = await _dbContext.Users.AsNoTracking().SingleOrDefaultAsync(b => b.UID == uid).ConfigureAwait(false); if (user == null || !user.IsAdmin && !user.IsModerator) context.Fail(); - logger.LogInformation("Admin/Moderator {uid} authenticated", uid); + _logger.LogInformation("Admin/Moderator {uid} authenticated", uid); } context.Succeed(requirement); diff --git a/MareSynchronosServer/MareSynchronosServer/Services/GrpcClientIdentificationService.cs b/MareSynchronosServer/MareSynchronosServer/Services/GrpcClientIdentificationService.cs deleted file mode 100644 index 0164223..0000000 --- a/MareSynchronosServer/MareSynchronosServer/Services/GrpcClientIdentificationService.cs +++ /dev/null @@ -1,241 +0,0 @@ -using Grpc.Core; -using MareSynchronosShared.Metrics; -using MareSynchronosShared.Protos; -using MareSynchronosShared.Services; -using MareSynchronosShared.Utils; -using System.Collections.Concurrent; - -namespace MareSynchronosServer.Services; - -public class GrpcClientIdentificationService : GrpcBaseService, IClientIdentificationService -{ - private readonly string _shardName; - private readonly ILogger _logger; - private readonly IdentificationService.IdentificationServiceClient _grpcIdentClient; - private readonly IdentificationService.IdentificationServiceClient _grpcIdentClientStreamOut; - private readonly IdentificationService.IdentificationServiceClient _grpcIdentClientStreamIn; - private readonly MareMetrics _metrics; - protected readonly ConcurrentDictionary OnlineClients = new(StringComparer.Ordinal); - private readonly ConcurrentDictionary RemoteCachedIdents = new(StringComparer.Ordinal); - private readonly ConcurrentQueue _identChangeQueue = new(); - - public GrpcClientIdentificationService(ILogger logger, - IdentificationService.IdentificationServiceClient gprcIdentClient, - IdentificationService.IdentificationServiceClient gprcIdentClientStreamOut, - IdentificationService.IdentificationServiceClient gprcIdentClientStreamIn, - MareMetrics metrics, IConfigurationService configuration) : base(logger) - { - _shardName = configuration.GetValueOrDefault(nameof(ServerConfiguration.ShardName), string.Empty); - _logger = logger; - _grpcIdentClient = gprcIdentClient; - _grpcIdentClientStreamOut = gprcIdentClientStreamOut; - _grpcIdentClientStreamIn = gprcIdentClientStreamIn; - _metrics = metrics; - } - - public bool IsOnCurrentServer(string uid) - { - return OnlineClients.ContainsKey(uid); - } - - public string? GetCharacterIdentForUid(string uid) - { - if (OnlineClients.TryGetValue(uid, out var ident)) - { - return ident.Ident.Ident; - } - - if (RemoteCachedIdents.TryGetValue(uid, out var cachedIdent)) - { - return cachedIdent.Ident.Ident; - } - - return null; - } - - public string? GetServerForUid(string uid) - { - if (OnlineClients.ContainsKey(uid)) - { - return _shardName; - } - - if (RemoteCachedIdents.TryGetValue(uid, out var cachedIdent)) - { - return cachedIdent.Ident.ServerId; - } - - return null; - } - - public async Task GetOnlineUsers() - { - var result = await InvokeOnGrpc(_grpcIdentClient.GetOnlineUserCountAsync(new ServerMessage())).ConfigureAwait(false); - if (result == default(OnlineUserCountResponse)) return OnlineClients.Count; - return result.Count; - } - - public string? GetUidForCharacterIdent(string characterIdent) - { - bool existsLocal = OnlineClients.Any(o => string.Equals(o.Value.Ident.Ident, characterIdent, StringComparison.Ordinal)); - if (existsLocal) - { - return OnlineClients.First(c => string.Equals(c.Value.Ident.Ident, characterIdent, StringComparison.Ordinal)).Key; - } - - bool existsCached = RemoteCachedIdents.Any(o => string.Equals(o.Value.Ident.Ident, characterIdent, StringComparison.Ordinal)); - if (existsCached) - { - return RemoteCachedIdents.First(c => string.Equals(c.Value.Ident.Ident, characterIdent, StringComparison.Ordinal)).Key; - } - - return null; - } - - public void MarkUserOffline(string uid) - { - _metrics.SetGaugeTo(MetricsAPI.GaugeAuthorizedConnections, OnlineClients.Count); - - if (OnlineClients.TryRemove(uid, out var uidWithIdent)) - { - _identChangeQueue.Enqueue(new IdentChange() - { - IsOnline = false, - UidWithIdent = uidWithIdent - }); - } - } - - public void MarkUserOnline(string uid, string charaIdent) - { - OnlineClients[uid] = new UidWithIdent() - { - Uid = new() - { - Uid = uid, - }, - Ident = new() - { - Ident = charaIdent, - ServerId = _shardName - } - }; - - _metrics.SetGaugeTo(MetricsAPI.GaugeAuthorizedConnections, OnlineClients.Count); - _identChangeQueue.Enqueue(new IdentChange() - { - IsOnline = true, - UidWithIdent = OnlineClients[uid] - }); - } - - private async Task StreamOnlineClientData(CancellationToken cts) - { - try - { - using var stream = _grpcIdentClientStreamOut.SendStreamIdentStatusChange(cancellationToken: cts); - _logger.LogInformation("Starting Send Online Client Data stream"); - await stream.RequestStream.WriteAsync(new IdentChangeMessage() - { - Server = new ServerMessage() - { - ServerId = _shardName - } - }, cts).ConfigureAwait(false); - - while (!cts.IsCancellationRequested) - { - if (_identChangeQueue.TryDequeue(out var result)) - { - await stream.RequestStream.WriteAsync(new() { IdentChange = result }, cts).ConfigureAwait(false); - } - else - { - await Task.Delay(10, cts).ConfigureAwait(false); - } - } - } - catch (OperationCanceledException) { return; } - catch - { - SetGrpcFaulty(); - } - } - - private async Task ReceiveOnlineClientData(CancellationToken cts) - { - try - { - using var stream = _grpcIdentClientStreamIn.ReceiveStreamIdentStatusChange(new ServerMessage() - { - ServerId = _shardName, - }, cancellationToken: cts); - _logger.LogInformation("Starting Receive Online Client Data stream"); - await foreach (var cur in stream.ResponseStream.ReadAllAsync(cts).ConfigureAwait(false)) - { - OnlineClients.Remove(cur.UidWithIdent.Uid.Uid, out _); - if (cur.IsOnline) - { - RemoteCachedIdents[cur.UidWithIdent.Uid.Uid] = cur.UidWithIdent; - } - else if (RemoteCachedIdents.TryGetValue(cur.UidWithIdent.Uid.Uid, out var existingIdent) - && string.Equals(existingIdent.Ident.ServerId, cur.UidWithIdent.Ident.ServerId, StringComparison.Ordinal)) - { - RemoteCachedIdents.TryRemove(cur.UidWithIdent.Uid.Uid, out _); - } - } - _logger.LogCritical("Receive Online Client Data Stream ended"); - } - catch (OperationCanceledException) { return; } - catch - { - SetGrpcFaulty(); - } - } - - protected override Task StartAsyncInternal(CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - - protected override async Task StopAsyncInternal(CancellationToken cancellationToken) - { - await ExecuteOnGrpc(_grpcIdentClient.ClearIdentsForServerAsync(new ServerMessage() { ServerId = _shardName }, cancellationToken: cancellationToken)).ConfigureAwait(false); - } - - protected override async Task OnGrpcRestore() - { - var msg = new ServerIdentMessage(); - msg.Idents.AddRange(OnlineClients.Select(c => new SetIdentMessage() - { - UidWithIdent = c.Value - })); - await _grpcIdentClient.RecreateServerIdentsAsync(msg).ConfigureAwait(false); - } - - protected override async Task PreStartStream() - { - await _grpcIdentClient.ClearIdentsForServerAsync(new ServerMessage() { ServerId = _shardName }).ConfigureAwait(false); - - RemoteCachedIdents.Clear(); - } - - protected override Task StartStream(CancellationToken ct) - { - _ = StreamOnlineClientData(ct); - _ = ReceiveOnlineClientData(ct); - return Task.CompletedTask; - } - - protected override async Task PostStartStream() - { - var remoteOnlineClients = await _grpcIdentClient.GetAllIdentsAsync(new ServerMessage() - { - ServerId = _shardName - }).ConfigureAwait(false); - foreach (var result in remoteOnlineClients.UidWithIdent) - { - RemoteCachedIdents[result.Uid.Uid] = result; - } - } -} diff --git a/MareSynchronosServer/MareSynchronosServer/Services/IClientIdentificationService.cs b/MareSynchronosServer/MareSynchronosServer/Services/IClientIdentificationService.cs deleted file mode 100644 index 2db87c4..0000000 --- a/MareSynchronosServer/MareSynchronosServer/Services/IClientIdentificationService.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace MareSynchronosServer.Services; - -public interface IClientIdentificationService : IHostedService -{ - string GetCharacterIdentForUid(string uid); - Task GetOnlineUsers(); - string GetServerForUid(string uid); - bool IsOnCurrentServer(string uid); - void MarkUserOffline(string uid); - void MarkUserOnline(string uid, string charaIdent); -} diff --git a/MareSynchronosServer/MareSynchronosServer/Services/IdentityService.cs b/MareSynchronosServer/MareSynchronosServer/Services/IdentityService.cs deleted file mode 100644 index 0f292cd..0000000 --- a/MareSynchronosServer/MareSynchronosServer/Services/IdentityService.cs +++ /dev/null @@ -1,161 +0,0 @@ -using Grpc.Core; -using MareSynchronosServer.Identity; -using MareSynchronosShared.Protos; -using Microsoft.AspNetCore.Authorization; - -namespace MareSynchronosServer.Services; - -internal class GrpcIdentityService : IdentificationService.IdentificationServiceBase -{ - private readonly ILogger _logger; - private readonly IdentityHandler _handler; - - public GrpcIdentityService(ILogger logger, IdentityHandler handler) - { - _logger = logger; - _handler = handler; - } - - public override async Task GetIdentForUid(UidMessage request, ServerCallContext context) - { - var result = await _handler.GetIdentForUid(request.Uid).ConfigureAwait(false); - return new CharacterIdentMessage() - { - Ident = result.CharacterIdent, - ServerId = result.ServerId - }; - } - - [AllowAnonymous] - public override Task GetOnlineUserCount(ServerMessage request, ServerCallContext context) - { - return Task.FromResult(new OnlineUserCountResponse() { Count = _handler.GetOnlineUsers(request.ServerId) }); - } - - public override Task ClearIdentsForServer(ServerMessage request, ServerCallContext context) - { - var idents = _handler.GetIdentsForServer(request.ServerId); - foreach (var entry in idents) - { - EnqueueIdentOffline(new UidWithIdent() - { - Ident = new CharacterIdentMessage() - { - Ident = entry.Value.CharacterIdent, - ServerId = entry.Value.ServerId - }, - Uid = new UidMessage() - { - Uid = entry.Key - } - }); - } - - _handler.ClearIdentsForServer(request.ServerId); - return Task.FromResult(new Empty()); - } - - public override Task RecreateServerIdents(ServerIdentMessage request, ServerCallContext context) - { - foreach (var identMsg in request.Idents) - { - _handler.SetIdent(identMsg.UidWithIdent.Uid.Uid, identMsg.UidWithIdent.Ident.ServerId, identMsg.UidWithIdent.Ident.Ident); - EnqueueIdentOnline(identMsg.UidWithIdent); - } - return Task.FromResult(new Empty()); - } - - public override async Task SendStreamIdentStatusChange(IAsyncStreamReader requestStream, ServerCallContext context) - { - await requestStream.MoveNext().ConfigureAwait(false); - var server = requestStream.Current.Server; - if (server == null) throw new System.Exception("First message needs to be server message"); - _handler.RegisterServerForQueue(server.ServerId); - _logger.LogInformation("Registered Server " + server.ServerId + " input stream"); - - while (await requestStream.MoveNext(context.CancellationToken).ConfigureAwait(false)) - { - var cur = requestStream.Current.IdentChange; - if (cur == null) throw new System.Exception("Expected client ident change"); - _handler.EnqueueIdentChange(cur); - - if (cur.IsOnline) - { - _handler.SetIdent(cur.UidWithIdent.Uid.Uid, cur.UidWithIdent.Ident.ServerId, cur.UidWithIdent.Ident.Ident); - } - else - { - _handler.RemoveIdent(cur.UidWithIdent.Uid.Uid, cur.UidWithIdent.Ident.ServerId); - } - } - - _logger.LogInformation("Server input stream from " + server + " finished"); - - return new Empty(); - } - - public override async Task ReceiveStreamIdentStatusChange(ServerMessage request, IServerStreamWriter responseStream, ServerCallContext context) - { - var server = request.ServerId; - _logger.LogInformation("Registered Server " + server + " output stream"); - - try - { - while (!context.CancellationToken.IsCancellationRequested) - { - while (_handler.DequeueIdentChange(server, out var cur)) - { - await responseStream.WriteAsync(cur).ConfigureAwait(false); - } - - await Task.Delay(10).ConfigureAwait(false); - } - } - catch - { - _logger.LogInformation("Server output stream to " + server + " is faulty"); - } - - _logger.LogInformation("Server output stream to " + server + " is finished"); - } - - public override Task GetAllIdents(ServerMessage request, ServerCallContext context) - { - var response = new UidWithIdentMessage(); - foreach (var item in _handler.GetIdentsForAllExcept(request.ServerId)) - { - response.UidWithIdent.Add(new UidWithIdent() - { - Uid = new UidMessage() - { - Uid = item.Key - }, - Ident = new CharacterIdentMessage() - { - Ident = item.Value.CharacterIdent, - ServerId = item.Value.ServerId - } - }); - } - - return Task.FromResult(response); - } - - private void EnqueueIdentOnline(UidWithIdent ident) - { - _handler.EnqueueIdentChange(new IdentChange() - { - IsOnline = true, - UidWithIdent = ident - }); - } - - private void EnqueueIdentOffline(UidWithIdent ident) - { - _handler.EnqueueIdentChange(new IdentChange() - { - IsOnline = false, - UidWithIdent = ident - }); - } -} \ No newline at end of file diff --git a/MareSynchronosServer/MareSynchronosServer/Services/LocalClientIdentificationService.cs b/MareSynchronosServer/MareSynchronosServer/Services/LocalClientIdentificationService.cs deleted file mode 100644 index 3e5fab6..0000000 --- a/MareSynchronosServer/MareSynchronosServer/Services/LocalClientIdentificationService.cs +++ /dev/null @@ -1,60 +0,0 @@ -using MareSynchronosShared.Protos; -using System.Collections.Concurrent; -using MareSynchronosServer.Identity; -using MareSynchronosShared.Services; -using MareSynchronosShared.Utils; - -namespace MareSynchronosServer.Services; - -public class LocalClientIdentificationService : IClientIdentificationService -{ - protected readonly ConcurrentDictionary OnlineClients = new(StringComparer.Ordinal); - private readonly IdentityHandler _identityHandler; - private readonly string _shardName; - - public LocalClientIdentificationService(IdentityHandler identityHandler, IConfigurationService config) - { - _identityHandler = identityHandler; - _shardName = config.GetValueOrDefault(nameof(ServerConfiguration.ShardName), string.Empty); - } - - public string GetCharacterIdentForUid(string uid) - { - return _identityHandler.GetIdentForUid(uid).Result.CharacterIdent; - } - - public Task GetOnlineUsers() - { - return Task.FromResult((long)_identityHandler.GetOnlineUsers(string.Empty)); - } - - public string GetServerForUid(string uid) - { - return _identityHandler.GetIdentForUid(uid).Result.ServerId; - } - - public bool IsOnCurrentServer(string uid) - { - return string.Equals(_identityHandler.GetIdentForUid(uid).Result.ServerId, _shardName, StringComparison.Ordinal); - } - - public void MarkUserOffline(string uid) - { - _identityHandler.RemoveIdent(uid, _shardName); - } - - public void MarkUserOnline(string uid, string charaIdent) - { - _identityHandler.SetIdent(uid, _shardName, charaIdent); - } - - public Task StartAsync(CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - - public Task StopAsync(CancellationToken cancellationToken) - { - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/MareSynchronosServer/MareSynchronosServer/Services/SystemInfoService.cs b/MareSynchronosServer/MareSynchronosServer/Services/SystemInfoService.cs index 0212551..d068a51 100644 --- a/MareSynchronosServer/MareSynchronosServer/Services/SystemInfoService.cs +++ b/MareSynchronosServer/MareSynchronosServer/Services/SystemInfoService.cs @@ -6,6 +6,7 @@ using MareSynchronosShared.Services; using MareSynchronosShared.Utils; using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; +using StackExchange.Redis; namespace MareSynchronosServer.Services; @@ -14,21 +15,21 @@ public class SystemInfoService : IHostedService, IDisposable private readonly MareMetrics _mareMetrics; private readonly IConfigurationService _config; private readonly IServiceProvider _services; - private readonly IClientIdentificationService _clientIdentService; private readonly ILogger _logger; private readonly IHubContext _hubContext; + private readonly IConnectionMultiplexer _redis; private Timer _timer; public SystemInfoDto SystemInfoDto { get; private set; } = new(); public SystemInfoService(MareMetrics mareMetrics, IConfigurationService configurationService, IServiceProvider services, - IClientIdentificationService clientIdentService, ILogger logger, IHubContext hubContext) + ILogger logger, IHubContext hubContext, IConnectionMultiplexer connectionMultiplexer) { _mareMetrics = mareMetrics; _config = configurationService; _services = services; - _clientIdentService = clientIdentService; _logger = logger; _hubContext = hubContext; + _redis = connectionMultiplexer; } public Task StartAsync(CancellationToken cancellationToken) @@ -47,7 +48,8 @@ public class SystemInfoService : IHostedService, IDisposable _mareMetrics.SetGaugeTo(MetricsAPI.GaugeAvailableWorkerThreads, workerThreads); _mareMetrics.SetGaugeTo(MetricsAPI.GaugeAvailableIOWorkerThreads, ioThreads); - var onlineUsers = (int)_clientIdentService.GetOnlineUsers().Result; + var endpoint = _redis.GetEndPoints().First(); + var onlineUsers = (_redis.GetServer(endpoint).Keys(pattern: "UID:*").Count()); SystemInfoDto = new SystemInfoDto() { OnlineUsers = onlineUsers, diff --git a/MareSynchronosServer/MareSynchronosServer/Startup.cs b/MareSynchronosServer/MareSynchronosServer/Startup.cs index f50d0ff..1c30e15 100644 --- a/MareSynchronosServer/MareSynchronosServer/Startup.cs +++ b/MareSynchronosServer/MareSynchronosServer/Startup.cs @@ -13,7 +13,6 @@ using MareSynchronosServer.Services; using MareSynchronosServer.Utils; using MareSynchronosServer.RequirementHandlers; using MareSynchronosShared.Utils; -using MareSynchronosServer.Identity; using MareSynchronosShared.Services; using Prometheus; using Microsoft.Extensions.Options; @@ -22,6 +21,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; using MareSynchronosServer.Authentication; +using StackExchange.Redis; namespace MareSynchronosServer; @@ -109,6 +109,12 @@ public class Startup options.Configuration.ChannelPrefix = "MareSynchronos"; }); } + + var options = ConfigurationOptions.Parse(redis); + options.ClientName = "Mare"; + options.ChannelPrefix = "UserData"; + ConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect(options); + services.AddSingleton(connectionMultiplexer); } private void ConfigureIpRateLimiting(IServiceCollection services) @@ -220,18 +226,6 @@ public class Startup RetryPolicy = null }; - services.AddGrpcClient(c => - { - c.Address = new Uri(mareConfig.GetValue(nameof(ServerConfiguration.MainServerGrpcAddress))); - }).ConfigureChannel(c => - { - c.ServiceConfig = new ServiceConfig { MethodConfigs = { noRetryConfig } }; - c.HttpHandler = new SocketsHttpHandler() - { - EnableMultipleHttp2Connections = true - }; - }); - services.AddGrpcClient("MainServer", c => { c.Address = new Uri(mareConfig.GetValue(nameof(ServerConfiguration.MainServerGrpcAddress))); @@ -244,8 +238,6 @@ public class Startup }; }); - services.AddSingleton(); - services.AddHostedService(p => p.GetService()); services.AddSingleton>(c => new MareConfigurationServiceClient( c.GetService>>(), c.GetService>(), @@ -261,8 +253,6 @@ public class Startup } else { - services.AddSingleton(); - services.AddSingleton(); services.AddSingleton, MareConfigurationServiceServer>(); services.AddSingleton, MareConfigurationServiceServer>(); @@ -323,7 +313,6 @@ public class Startup if (config.IsMain) { - endpoints.MapGrpcService().AllowAnonymous(); endpoints.MapGrpcService>().AllowAnonymous(); endpoints.MapGrpcService().AllowAnonymous(); } diff --git a/MareSynchronosServer/MareSynchronosServices/Discord/DiscordBot.cs b/MareSynchronosServer/MareSynchronosServices/Discord/DiscordBot.cs index 46461e9..5901ae2 100644 --- a/MareSynchronosServer/MareSynchronosServices/Discord/DiscordBot.cs +++ b/MareSynchronosServer/MareSynchronosServices/Discord/DiscordBot.cs @@ -6,7 +6,7 @@ using MareSynchronosShared.Data; using MareSynchronosShared.Services; using MareSynchronosShared.Utils; using Microsoft.EntityFrameworkCore; -using static MareSynchronosShared.Protos.IdentificationService; +using StackExchange.Redis; namespace MareSynchronosServices.Discord; @@ -16,19 +16,19 @@ internal class DiscordBot : IHostedService private readonly IServiceProvider _services; private readonly IConfigurationService _configurationService; private readonly ILogger _logger; - private readonly IdentificationServiceClient _identificationServiceClient; + private readonly IConnectionMultiplexer _connectionMultiplexer; private readonly DiscordSocketClient _discordClient; private CancellationTokenSource? _updateStatusCts; private CancellationTokenSource? _vanityUpdateCts; public DiscordBot(DiscordBotServices botServices, IServiceProvider services, IConfigurationService configuration, - ILogger logger, IdentificationServiceClient identificationServiceClient) + ILogger logger, IConnectionMultiplexer connectionMultiplexer) { _botServices = botServices; _services = services; _configurationService = configuration; _logger = logger; - this._identificationServiceClient = identificationServiceClient; + _connectionMultiplexer = connectionMultiplexer; _discordClient = new(new DiscordSocketConfig() { DefaultRetryMode = RetryMode.AlwaysRetry @@ -170,9 +170,11 @@ internal class DiscordBot : IHostedService _updateStatusCts = new(); while (!_updateStatusCts.IsCancellationRequested) { - var onlineUsers = await _identificationServiceClient.GetOnlineUserCountAsync(new MareSynchronosShared.Protos.ServerMessage()); - _logger.LogInformation("Users online: " + onlineUsers.Count); - await _discordClient.SetActivityAsync(new Game("Mare for " + onlineUsers.Count + " Users")).ConfigureAwait(false); + var endPoint = _connectionMultiplexer.GetEndPoints().First(); + var onlineUsers = await _connectionMultiplexer.GetServer(endPoint).KeysAsync(pattern: "UID:*").CountAsync(); + + _logger.LogInformation("Users online: " + onlineUsers); + await _discordClient.SetActivityAsync(new Game("Mare for " + onlineUsers + " Users")).ConfigureAwait(false); await Task.Delay(TimeSpan.FromSeconds(15)).ConfigureAwait(false); } } diff --git a/MareSynchronosServer/MareSynchronosServices/Discord/MareModule.cs b/MareSynchronosServer/MareSynchronosServices/Discord/MareModule.cs index ac9a504..5910b76 100644 --- a/MareSynchronosServer/MareSynchronosServices/Discord/MareModule.cs +++ b/MareSynchronosServer/MareSynchronosServices/Discord/MareModule.cs @@ -8,9 +8,9 @@ using Prometheus; using MareSynchronosShared.Models; using MareSynchronosShared.Utils; using MareSynchronosShared.Services; -using static MareSynchronosShared.Protos.IdentificationService; using Grpc.Net.ClientFactory; using MareSynchronosShared.Protos; +using StackExchange.Redis; namespace MareSynchronosServices.Discord; @@ -28,21 +28,21 @@ public class MareModule : InteractionModuleBase private readonly ILogger _logger; private readonly IServiceProvider _services; private readonly DiscordBotServices _botServices; - private readonly IdentificationServiceClient _identificationServiceClient; private readonly IConfigurationService _mareClientConfigurationService; private readonly GrpcClientFactory _grpcClientFactory; + private readonly IConnectionMultiplexer _connectionMultiplexer; private Random random = new(); public MareModule(ILogger logger, IServiceProvider services, DiscordBotServices botServices, - IdentificationServiceClient identificationServiceClient, IConfigurationService mareClientConfigurationService, - GrpcClientFactory grpcClientFactory) + IConfigurationService mareClientConfigurationService, + GrpcClientFactory grpcClientFactory, IConnectionMultiplexer connectionMultiplexer) { _logger = logger; _services = services; _botServices = botServices; - _identificationServiceClient = identificationServiceClient; _mareClientConfigurationService = mareClientConfigurationService; _grpcClientFactory = grpcClientFactory; + _connectionMultiplexer = connectionMultiplexer; } [SlashCommand("register", "Starts the registration process for the Mare Synchronos server of this Discord")] @@ -392,7 +392,7 @@ public class MareModule : InteractionModuleBase var lodestoneUser = await db.LodeStoneAuth.Include(u => u.User).SingleOrDefaultAsync(u => u.DiscordId == userToCheckForDiscordId).ConfigureAwait(false); var dbUser = lodestoneUser.User; var auth = await db.Auth.SingleOrDefaultAsync(u => u.UserUID == dbUser.UID).ConfigureAwait(false); - var identity = await _identificationServiceClient.GetIdentForUidAsync(new MareSynchronosShared.Protos.UidMessage { Uid = dbUser.UID }); + var identity = await _connectionMultiplexer.GetDatabase().StringGetAsync("UID:" + dbUser.UID).ConfigureAwait(false); var groups = await db.Groups.Where(g => g.OwnerUID == dbUser.UID).ToListAsync().ConfigureAwait(false); var groupsJoined = await db.GroupPairs.Where(g => g.GroupUserUID == dbUser.UID).ToListAsync().ConfigureAwait(false); @@ -405,7 +405,7 @@ public class MareModule : InteractionModuleBase eb.AddField("Vanity UID", dbUser.Alias); } eb.AddField("Last Online (UTC)", dbUser.LastLoggedIn.ToString("U")); - eb.AddField("Currently online: ", !string.IsNullOrEmpty(identity.Ident)); + eb.AddField("Currently online: ", !string.IsNullOrEmpty(identity)); eb.AddField("Hashed Secret Key", auth.HashedKey); eb.AddField("Joined Syncshells", groupsJoined.Count); eb.AddField("Owned Syncshells", groups.Count); @@ -419,9 +419,9 @@ public class MareModule : InteractionModuleBase eb.AddField("Owned Syncshell " + group.GID + " User Count", syncShellUserCount); } - if (isAdminCall && !string.IsNullOrEmpty(identity.Ident)) + if (isAdminCall && !string.IsNullOrEmpty(identity)) { - eb.AddField("Character Ident", identity.Ident); + eb.AddField("Character Ident", identity); } return eb; diff --git a/MareSynchronosServer/MareSynchronosServices/MareSynchronosServices.csproj b/MareSynchronosServer/MareSynchronosServices/MareSynchronosServices.csproj index d22884b..6833222 100644 --- a/MareSynchronosServer/MareSynchronosServices/MareSynchronosServices.csproj +++ b/MareSynchronosServer/MareSynchronosServices/MareSynchronosServices.csproj @@ -29,6 +29,7 @@ + diff --git a/MareSynchronosServer/MareSynchronosServices/Startup.cs b/MareSynchronosServer/MareSynchronosServices/Startup.cs index 3fb089d..da4c063 100644 --- a/MareSynchronosServer/MareSynchronosServices/Startup.cs +++ b/MareSynchronosServer/MareSynchronosServices/Startup.cs @@ -10,6 +10,7 @@ using MareSynchronosShared.Services; using Grpc.Net.ClientFactory; using Microsoft.Extensions.Options; using Microsoft.Extensions.DependencyInjection; +using StackExchange.Redis; namespace MareSynchronosServices; @@ -44,17 +45,12 @@ public class Startup RetryPolicy = null }; - services.AddGrpcClient(c => - { - c.Address = new Uri(mareConfig.GetValue(nameof(ServicesConfiguration.MainServerGrpcAddress))); - }).ConfigureChannel(c => - { - c.ServiceConfig = new ServiceConfig { MethodConfigs = { noRetryConfig } }; - c.HttpHandler = new SocketsHttpHandler() - { - EnableMultipleHttp2Connections = true - }; - }); + var redis = mareConfig.GetValue(nameof(ServerConfiguration.RedisConnectionString), string.Empty); + var options = ConfigurationOptions.Parse(redis); + options.ClientName = "Mare"; + options.ChannelPrefix = "UserData"; + ConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect(options); + services.AddSingleton(connectionMultiplexer); services.AddGrpcClient("MainServer", c => { diff --git a/MareSynchronosServer/MareSynchronosShared/Protos/mareservices.proto b/MareSynchronosServer/MareSynchronosShared/Protos/mareservices.proto index 8c9e8cf..a66d9e4 100644 --- a/MareSynchronosServer/MareSynchronosShared/Protos/mareservices.proto +++ b/MareSynchronosServer/MareSynchronosShared/Protos/mareservices.proto @@ -9,16 +9,6 @@ service FileService { rpc DeleteFiles (DeleteFilesRequest) returns (Empty); } -service IdentificationService { - rpc GetOnlineUserCount (ServerMessage) returns (OnlineUserCountResponse); - rpc GetIdentForUid (UidMessage) returns (CharacterIdentMessage); - rpc ClearIdentsForServer (ServerMessage) returns (Empty); - rpc RecreateServerIdents (ServerIdentMessage) returns (Empty); - rpc GetAllIdents (ServerMessage) returns (UidWithIdentMessage); - rpc SendStreamIdentStatusChange (stream IdentChangeMessage) returns (Empty); - rpc ReceiveStreamIdentStatusChange (ServerMessage) returns (stream IdentChange); -} - service ConfigurationService { rpc GetConfigurationEntry (KeyMessage) returns (ValueMessage); }