私は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を取得できないため、接続IDを渡すpublic 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;
}
null 参照例外をスローします。SignalR からデータを渡すときに expandoObject が null になっているようですが (私の考えです)、それについてはわかりません。
この個々のタイマーと、タイマーが経過したときに特定のユーザーにメッセージを送信する方法を教えてください。
サーバー側でタイマーを作成したいことに 注意してください。
サーバーからタイマーをリセットする
タイマーはサーバーでリセットできる必要があります。この場合、すべてにカスタム属性を配置します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 - ここでリセットタイマーを呼び出すにはどうすればよいですか?