add redis for character identification
This commit is contained in:
@@ -45,7 +45,7 @@ public class MareDbContext : DbContext
|
||||
{
|
||||
modelBuilder.Entity<Auth>().ToTable("auth");
|
||||
modelBuilder.Entity<User>().ToTable("users");
|
||||
modelBuilder.Entity<User>().HasIndex(c => c.CharacterIdentification);
|
||||
//modelBuilder.Entity<User>().HasIndex(c => c.CharacterIdentification);
|
||||
modelBuilder.Entity<FileCache>().ToTable("file_caches");
|
||||
modelBuilder.Entity<FileCache>().HasIndex(c => c.UploaderUID);
|
||||
modelBuilder.Entity<ClientPair>().ToTable("client_pairs");
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.8" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.6" />
|
||||
<PackageReference Include="prometheus-net" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -7,8 +7,8 @@ namespace MareSynchronosShared.Models
|
||||
[Key]
|
||||
[MaxLength(10)]
|
||||
public string UID { get; set; }
|
||||
[MaxLength(100)]
|
||||
public string CharacterIdentification { get; set; }
|
||||
//[MaxLength(100)]
|
||||
//public string CharacterIdentification { get; set; }
|
||||
[Timestamp]
|
||||
public byte[] Timestamp { get; set; }
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.Collections.Concurrent;
|
||||
using MareSynchronosShared.Metrics;
|
||||
|
||||
namespace MareSynchronosShared.Services;
|
||||
|
||||
public abstract class BaseClientIdentificationService : IClientIdentificationService
|
||||
{
|
||||
private readonly MareMetrics metrics;
|
||||
protected ConcurrentDictionary<string, string> OnlineClients = new();
|
||||
protected BaseClientIdentificationService(MareMetrics metrics)
|
||||
{
|
||||
this.metrics = metrics;
|
||||
}
|
||||
|
||||
public virtual int GetOnlineUsers()
|
||||
{
|
||||
return OnlineClients.Count;
|
||||
}
|
||||
|
||||
public string? GetUidForCharacterIdent(string characterIdent)
|
||||
{
|
||||
var result = OnlineClients.SingleOrDefault(u =>
|
||||
string.Compare(u.Value, characterIdent, StringComparison.InvariantCultureIgnoreCase) == 0);
|
||||
return result.Equals(new KeyValuePair<string, string>()) ? null : result.Key;
|
||||
}
|
||||
|
||||
public virtual string? GetCharacterIdentForUid(string uid)
|
||||
{
|
||||
if (!OnlineClients.TryGetValue(uid, out var result))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual void MarkUserOnline(string uid, string charaIdent)
|
||||
{
|
||||
OnlineClients[uid] = charaIdent;
|
||||
metrics.SetGaugeTo(MetricsAPI.GaugeAuthorizedConnections, OnlineClients.Count);
|
||||
}
|
||||
|
||||
public virtual void MarkUserOffline(string uid)
|
||||
{
|
||||
if (OnlineClients.TryRemove(uid, out _))
|
||||
{
|
||||
metrics.SetGaugeTo(MetricsAPI.GaugeAuthorizedConnections, OnlineClients.Count);
|
||||
}
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public virtual Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
metrics.SetGaugeTo(MetricsAPI.GaugeAuthorizedConnections, 0);
|
||||
OnlineClients = new();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Text;
|
||||
using MareSynchronosShared.Metrics;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using StackExchange.Redis;
|
||||
|
||||
namespace MareSynchronosShared.Services;
|
||||
|
||||
public class DistributedClientIdentificationService : BaseClientIdentificationService
|
||||
{
|
||||
private readonly IDistributedCache distributedCache;
|
||||
private readonly IConfiguration configuration;
|
||||
private const string RedisPrefix = "uidcache:";
|
||||
|
||||
public DistributedClientIdentificationService(MareMetrics metrics, IDistributedCache distributedCache, IConfiguration configuration) : base(metrics)
|
||||
{
|
||||
this.distributedCache = distributedCache;
|
||||
this.configuration = configuration.GetSection("MareSynchronos");
|
||||
}
|
||||
|
||||
public override int GetOnlineUsers()
|
||||
{
|
||||
var redis = configuration.GetValue<string>("RedisConnectionString");
|
||||
var conn = ConnectionMultiplexer.Connect(redis);
|
||||
var endpoint = conn.GetEndPoints().First();
|
||||
return conn.GetServer(endpoint).Keys(pattern: RedisPrefix + "*").Count();
|
||||
}
|
||||
|
||||
public override string? GetCharacterIdentForUid(string uid)
|
||||
{
|
||||
var localIdent = base.GetCharacterIdentForUid(uid);
|
||||
if (localIdent != null) return localIdent;
|
||||
var cachedIdent = distributedCache.Get(RedisPrefix + uid);
|
||||
return cachedIdent == null ? null : Encoding.UTF8.GetString(cachedIdent);
|
||||
}
|
||||
|
||||
public override void MarkUserOffline(string uid)
|
||||
{
|
||||
base.MarkUserOffline(uid);
|
||||
distributedCache.Remove(RedisPrefix + uid);
|
||||
}
|
||||
|
||||
public override void MarkUserOnline(string uid, string charaIdent)
|
||||
{
|
||||
base.MarkUserOnline(uid, charaIdent);
|
||||
distributedCache.Set(RedisPrefix + uid, Encoding.UTF8.GetBytes(charaIdent));
|
||||
}
|
||||
|
||||
public override Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (var uid in OnlineClients)
|
||||
{
|
||||
distributedCache.Remove(RedisPrefix + uid.Key);
|
||||
}
|
||||
return base.StopAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace MareSynchronosShared.Services;
|
||||
|
||||
public interface IClientIdentificationService : IHostedService
|
||||
{
|
||||
int GetOnlineUsers();
|
||||
string? GetUidForCharacterIdent(string characterIdent);
|
||||
string? GetCharacterIdentForUid(string uid);
|
||||
void MarkUserOnline(string uid, string charaIdent);
|
||||
void MarkUserOffline(string uid);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using MareSynchronosShared.Metrics;
|
||||
|
||||
namespace MareSynchronosShared.Services;
|
||||
|
||||
public class LocalClientIdentificationService : BaseClientIdentificationService
|
||||
{
|
||||
public LocalClientIdentificationService(MareMetrics metrics) : base(metrics)
|
||||
{
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user