Сессия заканчивается, даже если я работаю, время сеанса, Ajax и Symfony2

Я установил приложение для закрытия сеанса по таймауту, если пользователь ничего не делает за 10 минут. В config.yml у меня есть следующее:

session:
    handler_id:  ~
    cookie_lifetime: 600 # 10 minutes
    gc_maxlifetime: 600 # 10 minutes
    gc_probability: 1
    gc_divisor: 1

Я делаю вызов Ajax каждую минуту, чтобы проверить, будет ли сеанс близок к истечению срока действия или нет, и это то, что я проверяю:

public function isLoggedInAction(Request $request)
{
    $response = array();
    $response['authenticated'] = FALSE;
    $status = 200;
    $securityContext = $this->container->get('security.context');
    if ($securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
        $response['authenticated'] = TRUE;
    }

    return new JsonResponse($response, $status ?: 200);
}

По какой-то непонятной причине не работает, и каждые 10 минут сеанс закрывается независимо от того, работает ли я со страницей или нет, почему? Я что-то упустил?

Изменить 1 Выполнено новые значения, которые все еще не работают:

session:
    handler_id:  ~
    cookie_lifetime: 1800
    gc_maxlifetime: 600
    gc_probability: 1
    gc_divisor: 100

Пока я работал на странице, выполняя вызовы Ajax и некоторые другие задачи, сеанс был закрыт, поэтому он не работает. Единственное значение, которое, по-видимому, работает для меня до сих пор, установлено cookie_lifetime: 86400 #1 day, что для меня сумасшедшее!

Изменить 2 После того, как @acontell предложит исправить время и дату VM, я пытаюсь использовать эти новые значения (10 минут занимает слишком много времени, поэтому я изменил 3):

session:
    handler_id:  ~
    cookie_lifetime: 1800
    gc_maxlifetime: 180 # session will expire after 3 minutes of inactivity
    gc_probability: 1
    gc_divisor: 100

И также я установил дату/время на виртуальной машине, включив службу ntpd, и теперь дата прекрасна:

[[email protected] var]# date
 Sun Feb  1 18:35:17 VET 2015

Но через 5 минут (вызов функции был выполнен 5 раз) сессия все еще жива. Вот как я вызываю функцию isLoggedInAction() со стороны JavaScript:

$.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
    if( data.authenticated ){
        var timer = window.setInterval(function(){
            $.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
                if( !data.authenticated ){
                    window.clearInterval(timer);
                    $.growl({
                        message: 'La sesión ha expirado por inactividad, debe <a href=""><b>iniciar seción</b></a> nuevamente.'
                    }, {
                        type: "danger",
                        allow_dismiss: false,
                        timer: 10000,
                        animate: {
                            enter: 'animated fadeInDown',
                            exit: 'animated fadeOutUp'
                        },
                        onHide: function(){
                            location.reload();
                        }
                    });
                }
            }).fail(function(){});
        },60000);
    }
}).fail(function(){});

Смотрите изображение ниже:

enter image description here

Тест 3

После того, как все было хорошо работает, я сделал последний и окончательный тест: откройте приложение и оставайтесь нетронутым всю ночь (почти 8 часов) и удивите его, чтобы он никогда не закрывал сессию. Как показано ниже, посмотрите, сколько запросов запрашивает страница, и как сеанс все еще жив, почему?

enter image description here

Вызов Ajax производится каждый раз: 10.5 минут

$.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
    if( data.authenticated ){
        var timer = window.setInterval(function(){
            $.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
                if( !data.authenticated ){
                    window.clearInterval(timer);
                    $.growl({
                        message: 'La sesión ha expirado por inactividad, debe <a href=""><b>iniciar seción</b></a> nuevamente.'
                    }, {
                        type: "danger",
                        allow_dismiss: false,
                        timer: 10000,
                        animate: {
                            enter: 'animated fadeInDown',
                            exit: 'animated fadeOutUp'
                        },
                        onHide: function(){
                            location.reload();
                        }
                    });
                }
            }).fail(function(){});
        }, 210000);
    }
}).fail(function(){});

Настройки говорят, что сеанс должен быть продлен: 10 минут.

session:
    handler_id:  ~
    cookie_lifetime: 630000
    gc_maxlifetime: 630000 # session will expire after 10 minutes of inactivity 
    gc_probability: 1
    gc_divisor: 100

Время на сервере в порядке:

[[email protected] sencamer.dev]# date
Mon Feb  2 07:26:53 VET 2015

Что еще я должен проверить?

Тест 5

Хорошо, я все еще делаю тест, потому что это плохое поведение. Итак, это то, что я сделал для этого теста:

  • Откройте приложение и начните работу над ним.
  • В какой-то момент перестаньте работать и оставьте приложение сделать вызов Ajax, чтобы проверить, жив ли сеанс или нет. (сеанс еще жив, см. изображение ниже)
  • После этого первого вызова я продолжаю работать над приложением, так как изображение 2 показывает, но конец сеанса сюрпризов заканчивается, и приложение закрывается.

Почему? Что вызывает такое поведение? Правильно ли это на основе моих параметров?

Это изображение показывает первый и единственный вызов функции

enter image description here

После того, как звонок был выполнен, я продолжаю работать, но сеанс закрывается

enter image description here

Ответы

Ответ 1

Во-первых, следите за gc_probability и gc_divisor. Если оба значения равны единице, это означает, что вероятность запуска процесса сборщика мусора (GC) при каждой инициализации сеанса составляет gc_probability / gc_divisor = 1/1 = 1 (100%).

Вы можете оставить его по умолчанию или присвоить ему большее число, чтобы уменьшить вероятность вызова GC.

Например:

session:
        # handler_id set to null will use default session handler from php.ini
        handler_id:  ~
        cookie_lifetime: 600 # Ten minutes
        gc_probability: 1
        gc_divisor: 10000

Кроме того, если вы используете виртуальную машину, проверьте дату своего сервера, итоговый файл cookie сеанса будет отмечен временем истечения срока действия time() + cookie_lifetime, где время берется с сервера.

Возможно, что, если у сервера была плохая дата, cookie истечет немедленно. Представьте себе: дата сервера 2015-01-31, ваш браузер 2015-02-01. Сервер отправляет cookie, срок действия которого истекает на 2015-01-31 в 11:00, ваш браузер получает файл cookie с уже прошедшей датой истечения срока.

Ответ 2

попробуйте с этими параметрами:

gc_probability: 0
gc_divisor    : 1000