如何在ServiceStack中遍历所有会话?

我们的应用程序在每个公司都有公司和用途。 每家公司都有X个许可证。 我们使用的是类型化的会话类,该类包含公司的ID以及其他用户信息。 我需要添加到我们的身份validation过程中,检查当前登录是否会超过公司的许可证。 我相信这样做的方法是在所有与当前尝试登录的用户的companyId匹配的会话中计算所有公司ID,并将该计数与公司表中可用许可证的数量进行比较。 这是一种有效的方法吗? 如果是这样,请让我知道如何查询所有会话,因为我还没有想到它,我仍然有点新的ServiceStack。

使用ICacheClientExtended API

ICacheClientExtended接口现在支持GetKeysByPattern API,该API允许您扫描实现该接口的Cache Client上的匹配键。 目前通过以下方式实现:

  • MemoryCacheClient
  • OrmLiteCacheClient
  • Redis的
  • AWS DynamoDbCacheClient

此API现在允许GetAllKeys()上现在可用的新GetAllKeys()GetKeysStartingWith()扩展方法扫描所有缓存键。

 var prefix = IdUtils.CreateUrn(""); //= urn:iauthsession: var sessionKeys = Cache.GetKeysStartingWith(sessionPattern).ToList(); var userSessions = Cache.GetValues(sessionKeys); var existingSessions = userSessions.Values.Where(x => x != null).ToList(); 

其中existingSessions将包含活动用户会话列表。

性能取决于您拥有的活动会话数量,这取决于您网站的受欢迎程度。 您可能希望保留每个公司的一组会话ID,而不是搜索所有键,而是将它们添加到Session或Auth Event中的集合中。

这个新API可以从V4.0.45 + ServiceStack获得,现在可以在MyGet上使用 。

最新的DynamoDbCacheClient现在位于MyGet上的新ServiceStack.Aws NuGet包中,该包引用了AWS SDK中的最新v3。*包。


搜索底层缓存提供程序

另一个选择是直接从ICacheClient 缓存提供程序访问它们,如果它支持完全扫描,例如,如果您使用OrmLiteCacheClient在RDBMS中存储会话,则可以访问所有缓存条目:

 var sessionEntries = Db.Select(q => q.Where(x => x.Id.StartsWith("urn:iauthsession:"))); var userSessions = sessionEntries.Map(x => Db.Deserialize(x.Data)); 

如果你使用Redis进行缓存,你可以使用:

 var sessionKeys = Redis.SearchKeys("urn:iauthsession:*"); var sessions = Redis.GetValues(sessionKeys); 

另一种选择是通过注册可以在Redis SET或RDBMS表中维护的自定义会话或Auth事件 ,在每个用户登录时维护每个公司的所有会话ID列表。 在同一个注册钩子中,您可以使用ICacheClient.GetAll API并传入该公司的会话密钥来validation他们拥有多少个活动会话,例如:

 var sessions = Cache.GetAll(companySessionKeys); var activeSessions = sessions.Values.Where(x => x != null).ToList(); 

一点速度检查:

我正在使用InMemoryAuthRepository,如果我在缓存中有1000个会话,并且我获取它们,则需要21毫秒。 提取从4毫秒开始(1个会话),最长为21毫秒。

 sw.Restart(); IDictionary sessionList = cacheClient?.GetAll(cacheClient?.GetAllKeys()); sw.Stop(); totalMs += sw.ElapsedMilliseconds; counter2speed.Add(counter, totalMs);