title: How to create Login Session Timer for individual users
body: <p>I've been working on this <code>custom timer</code> I created for each user's <code>login session</code>. Until now I was'nt able to make an individual <code>timers</code> for each login session.  </p>
  
  <p><strong>Scenario:</strong>  </p>
  
  <p>When <code>User1</code> logs in, the <code>timer will start counting</code>. When <code>User2</code> logs in, the timer of Use1 will reset the value is same as the timer for User2.
  It seems that they have <code>one timer</code> (not individual).  </p>
  
  <p>Here is what I want to happen.  </p>
  
  <ul>
  <li>when user1 logs in, his timer will start counting.</li>
  <li>if the timer reach 900 seconds(15 minutes) it will pop-up some modal box that tells that his session has time out.</li>
  <li>the modal will show a count down for at least 30 seconds</li>
  <li>after the count down, user will be logged out automatically</li>
  <li>Every user must have their own timers</li>
  </ul>
  
  <p>I have done all of these except the last item <code>Every user must have their own timers</code>  </p>
  
  <p>Here is my code on creating a timer:  </p>
  
  <pre><code>public class SessionTimer
  {
      private static Timer timer;
  
      public static void StartTimer()
      {
          timer = new Timer();
          timer.Interval = (double)Utility.ActivityTimerInterval();
          timer.Elapsed += (s, e) =&gt; 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 &gt;= Utility.TimerValue())
          {
              timer.Stop();
              Hubs.Notifier.SessionTimeOut(TimeCount);
          }
          else
          {
              Hubs.Notifier.SendElapsedTime(TimeCount);
          }
  
          TimeCount++;
      }
  }  
  </code></pre>
  
  <p>After a successful login, I'm going to call the timer to start  </p>
  
  <pre><code>[HttpPost]
  public ActionResult SignIn(LoginCredentials info)
  {
      // Success full login
  
      SessionTimer.StartTimer();
  
  }  
  </code></pre>
  
  <p>Here is the signalr code on server:  </p>
  
  <pre><code>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&lt;SessionTimerHub&gt;();
          context.Clients.Client(SessionTimer.ConnectionID).alertClient(time);
      }
  
      public static void SendElapsedTime(int time)
      {
          var context = GlobalHost.ConnectionManager.GetHubContext&lt;SessionTimerHub&gt;();
          context.Clients.Client(SessionTimer.ConnectionID).sendElapsedTime(time);
      }
  }  
  </code></pre>
  
  <p>And the jquery code:  </p>
  
  <pre><code>$(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 &lt; 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');
          });
  
  });  
  </code></pre>
  
  <p>As you can see I'm doing this:  </p>
  
  <pre><code>timer.server.updateConnectionID($.connection.hub.id);  
  </code></pre>
  
  <p>to pass the connection id, because I can't get the id inside <code>public class Notifier</code>  </p>
  
  <p><strong>My failed solutions</strong>  </p>
  
  <p>I tried putting the <code>SessionTimer</code> in a <code>session</code> using <code>dynamic</code> and <code>ExpandoObject</code><br>
  e.g:  </p>
  
  <pre><code>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];
      }
  }  
  </code></pre>
  
  <p>And it successfully separated the timers. But when passing the connection id on my expandoobject variable<br>
  e.g:  </p>
  
  <pre><code>public void UpdateConnectionID(string id)
  {
      MyExpandoObject.MySessionTimer.ConnectionID = id;
  } 
  </code></pre>
  
  <p>it throws null reference exception. It seems that my expandoObject is getting null when passing data from SignalR (Just my thinking), but I'm not sure for that.  </p>
  
  <p>Please help me with this individual timers and sending message to specific users when their timers has elapsed.  </p>
  
  <p><strong>Please note</strong><br>
  I want to create the timer on Server Side.  </p>
  
  <p><strong>Resetting the timer from server</strong>  </p>
  
  <p>The timer must be able to reset on server. In this case I put custom attributes on every <code>AcrionReseult</code>  </p>
  
  <p>e.g.:  </p>
  
  <pre><code>[HttpPost]
  [BasecampAuthorize]
  public ActionResult LoadEmailType()
  {
      return Json(Enum.GetNames(typeof(EmailType)).ToList());
  }  
  </code></pre>
  
  <p>When the user passes <code>[BasecampAuthorize]</code> it means he made an activity.<br>
  Inside <code>[BasecampAuthorize]</code>  </p>
  
  <pre><code>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);
      }
  }  
  </code></pre>
  
  <p>@halter73 - How can I call the reset timer here?</p>