我一直在研究custom timer
我为每个用户创建的login session
. 到目前为止,我无法timers
为每个登录会话创建一个人。
设想:
User1
登录时,timer will start counting
. 登录时User2
,Use1 的计时器将重置为与 User2 的计时器相同的值。似乎他们有one timer
(不是个人)。
这就是我想要发生的事情。
- 当 user1 登录时,他的计时器将开始计时。
- 如果计时器达到 900 秒(15 分钟),它将弹出一些模式框,告诉他的会话已超时。
- 模态将显示倒计时至少 30 秒
- 倒计时后,用户将自动注销
- 每个用户都必须有自己的计时器
除了最后一项,我已经完成了所有这些Every user must have their own timers
这是我创建计时器的代码:
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();
}
这是服务器上的信号器代码:
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<SessionTimerHub>();
context.Clients.Client(SessionTimer.ConnectionID).alertClient(time);
}
public static void SendElapsedTime(int time)
{
var context = GlobalHost.ConnectionManager.GetHubContext<SessionTimerHub>();
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);
传递连接ID,因为我无法得到里面的IDpublic class Notifier
我失败的解决方案
我尝试将其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 变量上传递连接 id 时,
例如:
public void UpdateConnectionID(string id)
{
MyExpandoObject.MySessionTimer.ConnectionID = id;
}
它抛出空引用异常。从 SignalR 传递数据时,我的 expandoObject 似乎为空(只是我的想法),但我不确定。
请帮助我处理这个单独的计时器,并在他们的计时器到期时向特定用户发送消息。
请注意
我想在服务器端创建计时器。
从服务器重置计时器
计时器必须能够在服务器上重置。在这种情况下,我将自定义属性放在每个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 - 我如何在这里调用重置计时器?