我如何在ServiceStack中迭代所有会话
本文关键字:迭代 会话 ServiceStack | 更新日期: 2023-09-27 18:11:47
我们的应用程序在每个公司中都有公司和用途。每个公司有X个许可证。我们正在使用一个类型化的会话类,该类包含公司的id以及其他用户信息。我需要在我们的身份验证过程中添加一个检查,以查看当前登录是否会超过公司的许可证。我认为这样做的方法是获取所有会话中与当前尝试登录的用户的companyId匹配的所有公司id的计数,并将该计数与公司表中的可用许可证数量进行比较。这是一个有效的方法吗?如果是这样,请让我知道如何在所有会话中查询,因为我还没有弄清楚,我对ServiceStack还是有点陌生。
使用ICacheClientExtended API的
ICacheClientExtended
接口现在支持GetKeysByPattern
API,允许您扫描实现该接口的缓存客户端上的匹配密钥。目前这是通过以下方式实现的:
- MemoryCacheClient
- OrmLiteCacheClient
- 复述, AWS DynamoDbCacheClient
这个API现在使ICacheClient
上新的GetAllKeys()
和GetKeysStartingWith()
扩展方法可以扫描所有缓存键。
var prefix = IdUtils.CreateUrn<IAuthSession>(""); //= urn:iauthsession:
var sessionKeys = Cache.GetKeysStartingWith(sessionPattern).ToList();
var userSessions = Cache.GetValues<AuthUserSession>(sessionKeys);
var existingSessions = userSessions.Values.Where(x => x != null).ToList();
其中existingSessions
将包含活动用户会话列表。
性能将取决于你有多少活跃会话,这可能取决于你的网站的受欢迎程度。与搜索所有键不同,您可能希望为每个公司保留一组会话id,您可以通过将它们添加到session或Auth Event中的集合中来查看它们。
这个新的API可以从v4.0.45+的ServiceStack中获得,现在在MyGet上可用。
最新的DynamoDbCacheClient现在在新的ServiceStack中。MyGet上的Aws NuGet包引用了最新的v3。*来自AWS SDK的包。
搜索底层缓存提供程序
另一个选项是直接访问它们从你的ICacheClient
缓存提供商,如果它支持完整扫描,例如,如果你使用OrmLiteCacheClient
在RDBMS中存储会话,你可以访问所有的缓存条目:
var sessionEntries = Db.Select<CacheEntry>(q =>
q.Where(x => x.Id.StartsWith("urn:iauthsession:")));
var userSessions = sessionEntries.Map(x =>
Db.Deserialize<AuthUserSession>(x.Data));
如果你正在使用Redis缓存,你可以使用:
var sessionKeys = Redis.SearchKeys("urn:iauthsession:*");
var sessions = Redis.GetValues<AuthUserSession>(sessionKeys);
另一种选择是在每个用户登录时通过注册一个自定义会话或认证事件来维护每个公司的所有会话id列表,您可以在Redis SET或RDBMS表中维护这些会话id。在同一个注册钩子中,您可以通过使用ICacheClient.GetAll
API并传入该公司的会话密钥来验证他们有多少个活动会话,例如:
var sessions = Cache.GetAll<AuthUserSession>(companySessionKeys);
var activeSessions = sessions.Values.Where(x => x != null).ToList();
速度检查:
我使用InMemoryAuthRepository,如果我在缓存中有1000个会话,我取它们,它需要21毫秒。读取从4毫秒开始(对于1个会话),到21毫秒(对于1000个会话)
sw.Restart();
IDictionary<string, IAuthSession> sessionList = cacheClient?.GetAll<IAuthSession>(cacheClient?.GetAllKeys());
sw.Stop();
totalMs += sw.ElapsedMilliseconds;
counter2speed.Add(counter, totalMs);