Я работал над этим настраиваемым таймером
, который я создал для сеанса входа каждого пользователя
. До сих пор я не мог создавать индивидуальные таймеры
для каждого сеанса входа.
Scenario:
Когда User1
входит в систему, таймер начнет отсчет
. Когда User2
регистрируется, таймер Use1 сбрасывает значение, такое же, как таймер для User2.
Кажется, что у них есть один таймер
(не индивидуальный).
Вот что я хочу.
- Когда пользователь1 войдет в систему, его таймер начнет подсчет.
- Если таймер достигнет 900 секунд (15 минут), появится всплывающее окно с модальным полем, в котором говорится, что у его сеанса есть время.
- модальный покажет обратный отсчет не менее 30 секунд.
- после обратного отсчета пользователь автоматически выйдет из системы.
- Каждый пользователь должен иметь свои собственные таймеры
Я сделал все, кроме последнего элемента Каждый пользователь должен иметь свои собственные таймеры
Вот мой код при создании таймера:
public class SessionTimer
{
private static Timer timer;
public static void StartTimer()
{
timer = new Timer();
timer.Interval = (double)Utility.ActivityTimerInterval();
timer.Elapsed += (s, e) => MonitorElapsedTime();
timer.Start();
}
public static void ResetTimer()
{
TimeCount = 0;
timer.Stop();
timer.Start();
}
public static int TimeCount { get; set; }
public static string ConnectionID { get; set; }
private static void MonitorElapsedTime()
{
if (TimeCount >= Utility.TimerValue())
{
timer.Stop();
Hubs.Notifier.SessionTimeOut(TimeCount);
}
else
{
Hubs.Notifier.SendElapsedTime(TimeCount);
}
TimeCount++;
}
}
После успешного входа в систему я собираюсь вызвать таймер, чтобы начать
[HttpPost]
public ActionResult SignIn(LoginCredentials info)
{
//Success full login
SessionTimer.StartTimer();
}
Вот код signalr на сервере:
public class SessionTimerHub : Hub
{
public void SendTimeOutNotice(int time)
{
Clients.Client(Context.ConnectionId).alertClient(time);
}
public void CheckElapsedTime(int time)
{
Clients.Client(Context.ConnectionId).sendElapsedTime(time);
}
public void UpdateConnectionID(string id)
{
SessionTimer.ConnectionID = id;
}
}
public class Notifier
{
public static void SessionTimeOut(int time)
{
var context = GlobalHost.ConnectionManager.GetHubContext();
context.Clients.Client(SessionTimer.ConnectionID).alertClient(time);
}
public static void SendElapsedTime(int time)
{
var context = GlobalHost.ConnectionManager.GetHubContext();
context.Clients.Client(SessionTimer.ConnectionID).sendElapsedTime(time);
}
}
И код jquery:
$(function() {
/////////////////////////////////////////////////// SESSION TIMER
var timer = $.connection.sessionTimerHub, $modaltimer = $('#session_timer_elapsed'), tt = null;
timer.client.alertClient = function (time) {
var $count = $modaltimer.find('.timer'), wait = 180;
$count.text(wait);
$modaltimer.modal('show');
tt = setInterval(function() {
$count.text(wait--);
if (wait < 0) {
$.post('@Url.Action("Logout", "Auth")', function() { window.location.reload(); });
window.clearInterval(tt);
}
}, 1000);
};
timer.client.sendElapsedTime = function (time) {
console.log(time);
};
$.connection.hub.start().done(function() {
timer.server.updateConnectionID($.connection.hub.id);
});
$modaltimer.on('click', '.still_here', function() {
$.post('@Url.Action("ResetTimer", "Auth")');
$modaltimer.modal('hide');
window.clearInterval(tt);
}).on('click', '.log_out', function() {
$.post('@Url.Action("Logout", "Auth")', function() { window.location.reload(); });
$modaltimer.modal('hide');
});
});
Как вы видите, я делаю это:
timer.server.updateConnectionID($.connection.hub.id);
передать идентификатор соединения, потому что я не могу получить идентификатор внутри public class Notifier
My failed solutions
Я попытался помещать SessionTimer
в session
с помощью dynamic
и ExpandoObject
например:
public static dynamic Data
{
get
{
#region FAILSAFE
if (HttpContext.Current.Session[datakey] == null)
{
HttpContext.Current.Session[datakey] = new ExpandoObject();
}
#endregion
return (ExpandoObject)HttpContext.Current.Session[datakey];
}
}
И он успешно отделил таймеры. Но при передаче идентификатора соединения в моей переменной expandoobject
например:
public void UpdateConnectionID(string id)
{
MyExpandoObject.MySessionTimer.ConnectionID = id;
}
он выбрасывает исключение для NULL. Кажется, что мой expandoObject получает значение null при передаче данных из SignalR (только мое мышление), но я не уверен в этом.
Пожалуйста, помогите мне с этими отдельными таймерами и отправьте сообщение конкретным пользователям, когда их таймеры истекли.
Please note
I want to create the timer on Server Side.
Resetting the timer from server
Таймер должен иметь возможность сброса на сервере. В этом случае я помещаю пользовательские атрибуты на каждый AcrionReseult
например.:
[HttpPost]
[BasecampAuthorize]
public ActionResult LoadEmailType()
{
return Json(Enum.GetNames(typeof(EmailType)).ToList());
}
Когда пользователь передает [BasecampAuthorize]
, это означает, что он сделал операцию.
Внутри [BasecampAuthorize]
public class BasecampAuthorizeAttribute : AuthorizeAttribute
{
string url { get; set; }
public BasecampAuthorizeAttribute()
{
if (string.IsNullOrEmpty(url))
{
url = "~/SomeUrl";
}
}
public BasecampAuthorizeAttribute(string URL)
{
url = URL;
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.HttpContext.Response.Redirect(url);
}
else
{
//MUST RESET SESSION TIMER HERE
}
base.OnAuthorization(filterContext);
}
}
@ halter73 - Как я могу вызвать таймер сброса здесь?