locked
Check Session State Without Extending RRS feed

  • Question

  • User-960459514 posted

    Hi There,

    I have been googling this but cannot find exactly what i am looking for. I have an MVC application with a sql server database. When a user logs in i set a session as follows

    Session["UserId"] = UserId

    My users tend to work on multiple tabs at the same time under the same login. That is fine. What i want to do, is using an ajax request from the browser i want to check how long is left before the session state expires. My ajax request will poll the server every 1 minute, and I know my session state expires after 20 minutes, so after 18 minutes, the ajax request should return 2 minutes left, and after 19 minutes it should return 1 minute left, and after 20 minutes it should return 0.

    My problem is, when i make the first ajax request to the server, it actually extends the session state by another 20 minutes. So every ajax call results in the extension of the session by 20 minutes more.

    So I would like the c# code to check how long is left in the session, without actually extending the session.

    I think you are going to come back and tell me it is not possible, and if it is not possible, then i will start a new thread about how to implement a custom session provider. Things like setting timers in javascript, or storing the times in a cookie on the local computer will not work for me because of people working in multiple tabs.

    I appreciate any help being given.

    Thanks

    David

    Wednesday, January 20, 2016 4:16 PM

Answers

  • User475983607 posted

    IMHO, a cookie or local storage (as stated above) is the way to go since both are available by all browser tabs.  The trick is dealing with Unix time.  Here's a cookie example where the cookie value contains the number of milliseconds since 1/1/1970.  The button click gets the ball rolling by setting the cookie value to UTCNow. 

    Markup

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Session1.aspx.cs" Inherits="TestingWeb.Session1" Debug="false" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    
        <script type="text/javascript">
            var seconds = 2;
            var mark = 0;
            var now = 0;
            var elapsed = 0;
    
            var timerId = setInterval(timerHandler, seconds * 1000);
    
            function timerHandler() {
                //Compare now to the cookie timestamp from the server 
                mark = getCookie('sto');
                now = new Date().getTime();
                elapsed = (now - mark)/1000;
    
                //Seconds past
                document.getElementById('<%=Label1.ClientID%>').innerText = elapsed;
    
                //Stop the the timer at 20 minutes
                if (elapsed >= 20 * 60) {
                    clearInterval(timerId);
                }
            }
    
            function getCookie(name) {
                var regexp = new RegExp("(?:^" + name + "|;\s*" + name + ")=(.*?)(?:;|$)", "g");
                var result = regexp.exec(document.cookie);
                return (result === null) ? null : result[1];
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /><br />
            <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
        </div>
        </form>
    </body>
    </html>
    
       <script type="text/javascript">
                //mark = getCookie('sto');
                //now = new Date().getTime();
                //console.log(mark);
                //console.log(now);
                //elapsed = (now - mark) / 1000;
           //console.log(elapsed);
              </script>

    Code behind

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace TestingWeb
    {
        public partial class Session1 : System.Web.UI.Page
        {
    
            protected void Page_Load(object sender, EventArgs e)
            {
                Label1.Text = "--";
            }
    
            protected void Button1_Click(object sender, EventArgs e)
            {
                HttpCookie cookie = new HttpCookie("sto");
                cookie.Expires = DateTime.Now.AddDays(1);
               
                //Unix milliseconds since 1/1/1970
                DateTime baseDate = new DateTime(1970, 1, 1);
                TimeSpan diff = DateTime.UtcNow - baseDate;
                cookie.Value = diff.TotalMilliseconds.ToString();
                Response.Cookies.Add(cookie);
                Label1.Text = "--";
    
                Session["State"] = "Session 1";
            }
        }
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, January 26, 2016 9:47 PM
  • User614698185 posted

    Hi David,

    I use Javascript to create the sample in the master page, it will show the session time left minutes.

    <script type="text/javascript">
          var sessionTimeout = "<%= Session.Timeout %>";
            function DisplaySessionTimeout() {
                //assigning minutes left to session timeout to Label
                document.getElementById("<%= lblSessionTime.ClientID %>").innerText = sessionTimeout;
                sessionTimeout = sessionTimeout - 1;
    
                //if session is not less than 0
                if (sessionTimeout >= 0)
                    //call the function again after 1 minute delay
                    window.setTimeout("DisplaySessionTimeout()", 60000);
                else {
                    //show message box
                    alert("Your current Session is over.");
                }
            }
    </script> 

    Best Regards,

    Candice Zhou

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, January 28, 2016 7:16 AM

All replies

  • User614698185 posted

    Hi David,

    I think you misunderstand Session.Timeout. The Timeout property sets or returns the timeout period for the Session object for this application, in minutes. If the user does not refresh or request a page within the timeout period, the session will end.

    Best Regards,

    Candice Zhou

    Thursday, January 21, 2016 7:28 AM
  • User475983607 posted

    @dbrosnan, Session is based on the browser instance not tabs within the browser.   All tabs in a browser share the same Session cookie for a particular site. 

    Friday, January 22, 2016 11:04 PM
  • User-960459514 posted

    Hi There,

    Thank you for the response. I don't believe I am misunderstanding Session.Timeout as the inital response suggested, and i also understand that All tabs share the same Session Cookie. Maybe i was not clear with my question. I will try and give some more information.

    Let's say for example, a user logs into my system and when the user logs in I populate a value into a session property like the following.

    Session["UserId"] = 415;

    Let's say the user logged in at 4pm. I know that on my server the Session will timeout at 4.20pm because 20 minutes is the setting in the web.config for the session timeout.

    Now, from the web page on the clients computer, i have some ajax that is polling the server every 2 minutes. So at 4:02pm the ajax will poll the server. What i want to know, is at this time i want to check how long will it be before the Session Times out. The answer should be 18 minutes. But i do not know how to check this. When the ajax polls at 4:04pm the answer should be 16 minutes.

    You can ignore what i said about multiple tabs, it is not that relevant for my question. I just want to know when the session will expire. Does this make sense?

    Thank You
    David

    Tuesday, January 26, 2016 3:51 PM
  • User753101303 posted

    Hi,

    My first thought would be to use localStorage (if available). I would then keep here the date/time of the last request (and so the session ends x minutes later).

    I 'm not sure what you are using with Ajax but either you extend the session lifetime or you don't have the session available and more likely you do use it to store the last http query date/time? Or you would need to pass something to get this info from the server side.

    Tuesday, January 26, 2016 4:00 PM
  • User2053451246 posted

    As soon as you poll the server to see how much time is left the timer will be reset to 20 minutes.  You are keeping the session active by polling.

    Tuesday, January 26, 2016 4:08 PM
  • User475983607 posted

    IMHO, a cookie or local storage (as stated above) is the way to go since both are available by all browser tabs.  The trick is dealing with Unix time.  Here's a cookie example where the cookie value contains the number of milliseconds since 1/1/1970.  The button click gets the ball rolling by setting the cookie value to UTCNow. 

    Markup

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Session1.aspx.cs" Inherits="TestingWeb.Session1" Debug="false" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    
        <script type="text/javascript">
            var seconds = 2;
            var mark = 0;
            var now = 0;
            var elapsed = 0;
    
            var timerId = setInterval(timerHandler, seconds * 1000);
    
            function timerHandler() {
                //Compare now to the cookie timestamp from the server 
                mark = getCookie('sto');
                now = new Date().getTime();
                elapsed = (now - mark)/1000;
    
                //Seconds past
                document.getElementById('<%=Label1.ClientID%>').innerText = elapsed;
    
                //Stop the the timer at 20 minutes
                if (elapsed >= 20 * 60) {
                    clearInterval(timerId);
                }
            }
    
            function getCookie(name) {
                var regexp = new RegExp("(?:^" + name + "|;\s*" + name + ")=(.*?)(?:;|$)", "g");
                var result = regexp.exec(document.cookie);
                return (result === null) ? null : result[1];
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /><br />
            <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
        </div>
        </form>
    </body>
    </html>
    
       <script type="text/javascript">
                //mark = getCookie('sto');
                //now = new Date().getTime();
                //console.log(mark);
                //console.log(now);
                //elapsed = (now - mark) / 1000;
           //console.log(elapsed);
              </script>

    Code behind

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace TestingWeb
    {
        public partial class Session1 : System.Web.UI.Page
        {
    
            protected void Page_Load(object sender, EventArgs e)
            {
                Label1.Text = "--";
            }
    
            protected void Button1_Click(object sender, EventArgs e)
            {
                HttpCookie cookie = new HttpCookie("sto");
                cookie.Expires = DateTime.Now.AddDays(1);
               
                //Unix milliseconds since 1/1/1970
                DateTime baseDate = new DateTime(1970, 1, 1);
                TimeSpan diff = DateTime.UtcNow - baseDate;
                cookie.Value = diff.TotalMilliseconds.ToString();
                Response.Cookies.Add(cookie);
                Label1.Text = "--";
    
                Session["State"] = "Session 1";
            }
        }
    }

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, January 26, 2016 9:47 PM
  • User614698185 posted

    Hi David,

    I use Javascript to create the sample in the master page, it will show the session time left minutes.

    <script type="text/javascript">
          var sessionTimeout = "<%= Session.Timeout %>";
            function DisplaySessionTimeout() {
                //assigning minutes left to session timeout to Label
                document.getElementById("<%= lblSessionTime.ClientID %>").innerText = sessionTimeout;
                sessionTimeout = sessionTimeout - 1;
    
                //if session is not less than 0
                if (sessionTimeout >= 0)
                    //call the function again after 1 minute delay
                    window.setTimeout("DisplaySessionTimeout()", 60000);
                else {
                    //show message box
                    alert("Your current Session is over.");
                }
            }
    </script> 

    Best Regards,

    Candice Zhou

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, January 28, 2016 7:16 AM