简体   繁体   English

使用系统时钟进行准确的空闲超时警告

[英]Using system clock for accurate idle timeout warning

I am working on a modal which will alert users of a pending logout due to idle time. 我正在开发一个模式,它将提醒用户由于空闲时间而挂起的注销。 Overall it works, but I notice the timer is not 100% accurate. 总的来说它有效,但我注意到计时器不是100%准确。 I know there are issues with setInterval and accuracy. 我知道setInterval和准确性存在问题。 I still seeing discrepancies and will welcome a suggestion on how to improve my code. 我仍然看到差异,并欢迎提出如何改进我的代码的建议。

var sessionTimeoutPeriod = 240;
var state = "L";
var timeoutPeriod = sessionTimeoutPeriod * 1000;
var logout = Math.floor(timeoutPeriod / 60000);
var idleInterval;

if (state == "L" || state == "O" || state == "C") {
var idleTime = 0;

$(document).ready(function() {
    //Zero the idle timer on mouse movement.
    $(this).mousemove(function(e) {
        idleTime = 0;
        console.log("The mouse moved, idle time = " + idleTime);
    });
    $(this).keypress(function(e) {
        idleTime = 0;
        console.log("A key was pressed, idle time = " + idleTime);
    });


    idleInterval = setInterval(timerIncrement, 60000); // 1 minute

});

function timerIncrement() {

  idleTime++;
    console.log("The total idle time is "+idleTime+  " minutes.");

    if (idleTime >= 1) {
    console.log("The modal will fire if idle time = " +idleTime);
        var modal = new window.AccessibleModal({
        mainPage: $('#main'),
            overlay: $('#overlay').css('display', 'block'),
            modal: $('#modal-session-timeout'),
            prevFocus: $('#main')
        });

         modal.show();

         $('#modal-overlay').removeClass('opened');

        $('.js-timeout-refresh, .xClose').click(function() {
            modal.hide();
            $('#overlayTY').css('display', 'none');
            idleTime = 0;

            console.log("The total idle time is "+idleTime+  " minutes.");
        });
        $('.js-timeout-session-end').click(function() {
            modal.hide();
            $('#overlay').css('display', 'none');
            endSession();
        });
        console.log(idleTime);
    }
    if (idleTime == logout) { // 9 minutes
        endSession();
    }

    var endSession = function() {
        document.location.replace(logoutPageUrl);
    };
}

} }

Instead of relying on the interval to determine how much time has passed, you could validate how much time has passed manually by comparing the current time against the time since last activity. 您可以通过比较当前时间与自上次活动以来的时间来验证手动传递的时间,而不是依赖间隔来确定已经过了多少时间。

This way you can increase the checking interval without having to modify the code. 这样,您可以增加检查间隔,而无需修改代码。 The discrepancy will never be higher then then the interval timeout now, the discrepancy will also not change incrementally, it will always be lower or equal to the interval ( in worst case scenario ). 差异永远不会高于现在的间隔超时,差异也不会逐渐变化,它总是低于或等于间隔(在最坏的情况下)。

Here is a basic example. 这是一个基本的例子。

var sessionTimeoutPeriod = 240;
var timeoutPeriod = sessionTimeoutPeriod * 1000;
var oneMinute = 60000;
var showIdlePopUpTimeOut = oneMinute * 2;
var lastActivity = new Date();

function getIdleTime() {
    return new Date().getTime() - lastActivity.getTime();
}

$(document).ready(function () {
    //Zero the idle timer on mouse movement.
    $(this).mousemove(function (e) {
        console.log("The mouse moved, idle time = " + getIdleTime());
        lastActivity = new Date();
    });
    $(this).keypress(function (e) {
        console.log("A key was pressed, idle time = " + getIdleTime());
        lastActivity = new Date();
    });

    setInterval(checkIdleTime, 5000);
});

function endSession() {
    document.location.replace(logoutPageUrl);
};

function checkIdleTime() {
    var idleTime = getIdleTime();
    console.log("The total idle time is " + idleTime / oneMinute + " minutes.");

    if (idleTime > showIdlePopUpTimeOut) {
        var modal = new window.AccessibleModal({
            mainPage: $('#main'),
            overlay: $('#overlay').css('display', 'block'),
            modal: $('#modal-session-timeout'),
            prevFocus: $('#main')
        });

        modal.show();

        $('#modal-overlay').removeClass('opened');

        $('.js-timeout-refresh, .xClose').click(function () {
            modal.hide();
            $('#overlayTY').css('display', 'none');
            lastActivity = new Date();
        });
        $('.js-timeout-session-end').click(function () {
            modal.hide();
            $('#overlay').css('display', 'none');
            endSession();
        });
        console.log(lastActivity);
    }
    if (idleTime > timeoutPeriod) { // 4 minutes
        endSession();
    }

}

The problem is that your function "timerIncrement" checks the difference every minute after loading the page, so you will never get exact 1 minute after last activity.Changing interval from 60000 to 1000 will solve the issue. 问题是你的函数“timerIncrement”在加载页面后每分钟检查一次差异,所以在最后一次活动后1分钟你将永远不会得到。改变间隔从60000到1000将解决问题。

You don't even need to calculate diff, you can just reset timeout every time there is activity. 你甚至不需要计算diff,你可以在每次有活动时重置超时。 like this: 像这样:

$(this).on("mousemove keypress", function(e) {
        clearInterval(idleInterval);
        idleInterval = setTimeout(functionThatExecutesAfter1minInactivity, 60000);
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM