如何使用Timeout-dialog JS在Mousemove或Keydown事件上保持会话活动?

时间:2017-05-18 07:31:06

标签: javascript jquery timeout-dialog.js

我在我的应用程序中使用timeout-dialog.JS,在5分钟后使非活动用户的会话到期。但是我有输入网格,其中用户可以添加多个记录,然后在添加假设说10条记录后,他进行了保存,但是他花了超过5分钟输入所有这些细节,当他去保存或当他说是让我登录超时对话框弹出屏幕重新加载,他丢失了所有数据。

我想要的是,如果移动鼠标或按键,会话应该重置。

为实现这一点,我尝试在布局页面中添加mousemove和keydown事件,如下所示:

     <script>
    $(function () {
        var fnTimeOut = function () {
            $.timeoutDialog.setupDialogTimer({
                timeout: 300,
                countdown: 60,
                logout_redirect_url: '@Url.Action("LogOff", "Account")',
                keep_alive_url: '@Url.Action("Keepalive", "Account")'
            });
        };
        fnTimeOut();

        $(this).mousemove(function () {
            $.timeoutDialog.setupDialogTimer({
                timeout: 300,
                countdown: 60,
                logout_redirect_url: '@Url.Action("LogOff", "Account")',
                keep_alive_url: '@Url.Action("Keepalive", "Account")'
            });             
        });

        $(this).keydown(function () {
            $.timeoutDialog.setupDialogTimer({
                timeout: 300,
                countdown: 60,
                logout_redirect_url: '@Url.Action("LogOff", "Account")',
                keep_alive_url: '@Url.Action("Keepalive", "Account")'
            });          
        });
    });
</script>

但是这让我警觉地说,页面没有响应KILL或WAIT选项。

那么有什么方法可以在mousemove和keydown事件上使用timeout-dialog JS进行会话重置?

非常感谢任何帮助。 感谢。

2 个答案:

答案 0 :(得分:0)

像这样的原始mousemove事件监听器对于你的目的来说是过度的,因为它可以每秒发出数百个事件,如果你正在执行更重的操作,肯定会杀死你的应用程序。我可以看到你可以做的两件事:

  • 限制事件,因此它们每N秒仅执行一次 - &gt;见Throttle
  • 找到一种方法只重置超时对话框的内部计时器。查看源代码内部并查看API中是否有任何内容可以执行此操作,而不是每次都设置一个全新的对话框(我怀疑它并不高效)。如果您需要任何进一步的帮助,请告诉我。

如果您只想让后端会话保持活动状态,可以像这样调用保持活动的URL:

var callKeepAlive = _.throttle(function () {
  $.get( "<YOUR KEEP-ALIVE URL>", function( data ) {
    console.log('keep-alive called')
  });
}, 1000);

然后在mousemove / keyup事件侦听器中执行callKeepAlive()

答案 1 :(得分:0)

我在检查XMLHttp的浏览器兼容性时会遇到这种情况,并在此处随机浏览器线程。想想我会给出我想出的工作实例,因为我很快就需要类似的东西,并认为这个问题可以用更大的例子来做。

底部的代码非常少

请原谅我这有点乱,这是一个原始的例子。

<?php
    // Do not forget session start if copying into your own code..
    if (isset($_GET['keepalive'])) {
        header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");
        header('Content-Type: application/json');
        $boolStatusOfSession = TRUE;        // Something like: $boolStatusOfSession = (isset($_SESSION['MyTokenWhenSignedIn']) ? TRUE : FALSE);
        echo json_encode(array('status'=>$boolStatusOfSession));
        exit;
    }
?>
<html>
    <head></head>
    <body>
        <p>This script will throttle the mouse movement event to a rate of once per second max and perform a keep alive request to the same page along with a json response of the session status</p>
        <p id="debugbox"><b>Server Keep Alive: </b>please wait for the timer (10 seconds)</p>
        <p id="debugbox2"></p>

        <script>
            var elmDebug = document.getElementById('debugbox');
            var elmDebug2 = document.getElementById('debugbox2');
            var idleStart = Math.floor(Date.now() / 1000);

            function keepAlivePoster() {
                objHttp = new XMLHttpRequest();
                objHttp.onreadystatechange = function() {
                    var strDebug = "<b>Server Keep Alive: </b> ";
                    if (objHttp.readyState == XMLHttpRequest.DONE) {
                        idleStart = Math.floor(Date.now() / 1000);  
                        objResp = JSON.parse(objHttp.responseText);
                        if (objResp.hasOwnProperty('status') && objResp.status == true) {
                            // DO STUFF HERE WHEN SIGNED IN (Or do nothing at all)
                            strDebug += "Signed In, ";
                        } else {
                            // DO STUFF HERE WHEN SIGNED OUT (A window reload if your page can handle the session change)
                            strDebug += "Signed Out, "; // Or does not exist / error.. best to use a int status
                        }
                    }
                    elmDebug.innerHTML = strDebug + "Updated at " + Math.floor(Date.now() / 1000);
                    elmDebug2.innerHTML = '<b>Mouse Move Event: </b> Idle timer reset to ' + idleStart;
                }
                objHttp.open('GET', '?keepalive');
                objHttp.send(null);
            };


            function throttleController (callback, limit) {     // TAKEN FROM: https://jsfiddle.net/jonathansampson/m7G64/
                var wait = false;                  // Initially, we're not waiting
                elmDebug2.innerHTML = '<b>Mouse Move Event: </b> Idle timer reset to ' + idleStart;
                return function () {               // We return a throttled function
                    if (!wait) {                   // If we're not waiting
                        callback.call();           // Execute users function
                        wait = true;               // Prevent future invocations 
                        setTimeout(function () {wait = false;}, limit); // After a period of time, allow future invocations again
                    }
                }
            }           
            window.addEventListener("mousemove", throttleController(keepAlivePoster, 10000));       // Allow "idleCallback" to run at most 1 time every 10 seconds

        </script>
    </body>
</html>

当然有一些代码可以删除(调试等等,所以一个简单的基本脚本示例)

最小代码

function keepAlivePoster() {
    objHttp = new XMLHttpRequest();
    objHttp.open('GET', '?keepalive');
    objHttp.send(null);
};
function throttleController (callback, limit) {     // TAKEN FROM: https://jsfiddle.net/jonathansampson/m7G64/
    var wait = false;  return function () {              
        if (!wait) { callback.call();  wait = true; setTimeout(function () {wait = false;}, limit); }
    }
}           
window.addEventListener("mousemove", throttleController(keepAlivePoster, 10000));

您要为要覆盖的任何其他事件复制的最后一行,当您使用多个事件时,您还希望在更高的范围/全局上创建等待变量。

为什么php状态/代码

首先,这将是在html生成之前包含的另一个文件中的所有内容..但理想情况下,您希望GET请求尽可能小,只需要一些规则等等。所以我已经禁用页面缓存的能力,浏览器​​可以轻松使用json响应,同时提供简单的检查以在需要时重定向/重新加载。