2015-01-12 2 views
0

Я использую состояние сеанса ASP.Net, используя NuGet RedisSessionStateProvider.Redis Session State Provider invalidate session

Я потребляя сессии данных из приложения, используя что-то вроде этого:

public UserSessionData GetUserSessionData() 
{ 
    if (HttpContext.Current.Session == null || HttpContext.Current.Session["Key"] == null) 
    { 
     UserSessionData sessionData = ReadSessionFromDatabase(); 
     HttpContext.Current.Session.Add("Key", sessionData); 
     return sessionData; 
    } 
    else 
    { 
     return (UserSessionData)HttpContext.Current.Session["Key"]; 
    } 
} 

С описанным выше способом, в первый раз значение считывается из базы данных и хранятся в сессии (Redis Cache). В следующий раз, когда запрашивается значение, он считывается из Redis Cache без обращения к SQL.

Он отлично работает. Иногда, когда мне нужно аннулировать значения кеширования и принудительно читать из базы данных, я вызываю HttpContext.Current.Session.Abandon(). Это делается в качестве примера, когда пользователь меняет свой план.

Представьте ситуацию, когда мне нужно сделать недействительным кеш, поскольку некоторые изменения в базе данных, но это изменение не вызывает пользователя. Это изменение выполняется другим веб-сайтом (некоторым внутренним веб-сайтом для управления пользователями) или выполняется Webhook (уведомление о смене плана для пользователя). Как бы вы заставили пользователя повторно использовать данные из базы данных (удалить кэшированные данные) когда это не является триггером в HttpContext?

Я проверил промывку всего кекса redis flushdb, и он работает. Но, вне курса, он заставит весь сеанс пользователя читать данные снова. Как бы вы отменили кеширование только для некоторого пользователя?

ответ

1

Вы можете сделать Session.Abandon(), если вы находитесь внутри приложения. Но здесь вы хотите удалить сеанс из Redis из внешнего приложения. Вы можете это сделать, если знаете имя приложения (тот, который вы указали в файле web.config) и идентификатор сеанса.

Данные сеанса хранятся внутри Redis as _ Данные и некоторые поддерживающие внутренние данные хранятся внутриВнутренний. Если пользователь одновременно запускает другую страницу, вы можете увидеть _Write_Lock.

Если вы удалите все три из Redis, это в основном эквивалентно выполнению Session.Abandon(). Если вы собираетесь делать это с помощью программы C#, используя StackExchange.Redis, я бы рекомендовал удалить ее с помощью LUA-скрипта, поэтому все три будут удалены сразу, и никакая другая команда не сможет вмешаться.

У вас должно быть место, где вы можете найти, что запись в базе данных была изменена и, при необходимости, запустить этот код.

string applicationName = "<Actual Application Name>"; 
 
string sessionId = "<Actual Session Id>"; 
 

 
RedisKey dataKey = String.Format("{0}_{1}_Data", applicationName, sessionId); 
 
RedisKey internalKey = String.Format("{0}_{1}_Internal", applicationName, sessionId); 
 
RedisKey writeLockKey = String.Format("{0}_{1}_Write_Lock", applicationName, sessionId); 
 

 
RedisKey[] keys = new RedisKey[3]; 
 
keys[0] = dataKey; 
 
keys[1] = internalKey; 
 
keys[2] = writeLockKey; 
 

 
string removeSessionScript = (@" 
 
    redis.call('DEL',KEYS[1]) 
 
    redis.call('DEL',KEYS[2]) 
 
    redis.call('DEL',KEYS[3])" 
 
    ); 
 

 
db.ScriptEvaluate(removeSessionScript, keys, null);

+0

как я знаю Sesssion ID вне приложения? В качестве примера можно получить все идентификаторы, связанные с пользователем. –

Смежные вопросы