LCDS & Flex - Предотвращение ошибок DuplicateHTTPSession после выхода из системы - PullRequest
5 голосов
/ 18 ноября 2011

У меня есть стек flex / LCDS, где я нахожу, что после выхода из системы я часто (но не всегда) начинаю получать Duplicate HTTP Session ошибки на клиенте.

Вот важные факты из стека:

  • Flex-клиент имеет функцию входа / выхода из приложения в приложении.Страница не обновляется после выхода из системы.(Следовательно, приложение Flex и базовый mx.messaging.FlexClient остаются инициализированными)
  • У пользователя может быть открыто несколько вкладок.
  • per-client-authentication установлен на false - мы пытаемся добиться единого входа (интеграции с CAS), поэтому принцип пользователя привязан к JSession.
  • Проблема наиболее очевидна, когдаиспользование длинного опроса для обмена сообщениями и когда открыты две (или более) вкладки.
  • Эту проблему очень трудно воспроизвести при использовании RTMP или потоковых каналов.
  • Пользователь привязан к JSession - т. Е. Если он входит в систему на Tab1, он становится зарегистрированным на Tab2,
  • Когда пользователь выходит из любой вкладки, Jsession становится недействительным.

Вот моя текущая теория относительно причины проблемы:

  • Tab1(T1) Запускает клиент -> Выпущенный ClientId1 (C1) -> JSession1 (J1) создан
  • Tab2 (T2) Запускает клиент -> Выпущенный ClientId2 (C2) -> Соединения Журналы J1
  • T1in -> J1 не затронут
  • T2 входит в систему -> J1 не затронут
  • T1 & T2 Обе подписываются, начинают опрос через amflongpolling
  • T1 отправляет выход -> J1 Invalidated -> J2 создан
  • T2 отправляет опрос (против J1)
  • Выход из T1 завершается, возвращается с J2, обновляет cookie

Последние два вызова создают конфликт, когда LCDS видит, что FlexClient, по-видимому, связан с 2 JSessions.

В результате получена ошибка в соответствии с приведенным ниже описанием:

Server.Processing.DuplicateSessionDetected Обнаружены дубликаты FlexSessions на основе HTTP, как правило, из-за удаленного узлаВключение сеансовых файлов cookie.Сеансовые куки должны быть включены для правильного управления клиентским соединением.

Примечание: я смог воссоздать проблему в отдельном проекте. Я считаю, что это непроблема с кодом нашего приложения, вместо этого вызванная состоянием Stateful / session и конфликтами между несколькими вкладками, совместно использующими один и тот же сеанс.

В общем, я считаю, что проблема вызвана тем, что сеанс недействителен на сервере какрезультат вызовов из одной вкладки, но перед отправкой ответа в браузер для информирования его о новой JSession вызовы выполняются в рамках старой Jsession.

Какие существуют подходящие стратегии для защиты от этой проблемы с дублированием сеанса?


Обновление

Чтобы уточнить, хотя сценарий похож на рассмотренный здесь , существуют тонкие различия, которые делают решения в этой статье неуместными.

В частности, в статье обсуждается предотвращение дублирования сессий путем контроля первоначальное создание JSessions в обоих браузерах с использованием JSP или организованного вызова RemoteObject.

Flex фактически помогает в этом процессе, предотвращая исходящие вызовы RemoteObject до тех пор, покаопределена локальная переменная FlexClient DSid, показывающая, что начальный сеанс установлен.

Мой сценарий отличается, поскольку JSession (и связанные с ним объекты FlexSession / ClientSlex FlexClient на стороне клиента) уже были установлены один раз (используя методы, описанные в этой статье) и впоследствии аннулированные через выход из системы - что вызывает session.invalidate() - уничтожение JSession.

Проблема возникает, когда Tab2 отправляет вызов с устаревшей JSession, дублирующая ошибка сеанса HTTP.Затем ситуация усложняется: например, когда LCDS выдает ошибку DuplicateHTTPSession, она также делает недействительными все известные Jsessions, присоединенные к клиенту, что означает, что Tab1 - который был в порядке - теперь имеет устаревшую JSession.В следующий раз, когда Tab1 отправляет вызов, ИТ-служба вызывает ошибку DuplicateHTTPSession, и цикл повторяется.

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

 // Reset DSid to get a new FlexSession established on LCDS
   use namespace mx_internal

   public function resetFlexSession()
   {
        FlexClient.getInstance().id = null;  
        // Note - using FlexClient.NULL_ID also doesn't work.
   }

Ответы [ 3 ]

1 голос
/ 23 ноября 2011

Я чувствую к вам - я боролся с этим в течение долгого времени и никогда не находил решения, но нашел исправление , которое сработало для меня , так что, надеюсь, оно по крайней мере будет держать эту проблему под контролем, пока вы может найти виновника. (И если вы это сделаете, пожалуйста, напишите здесь).

Теперь у меня немного другая среда, чем у вас (я использую CF на бэкэнде), так что имейте это в виду.

Я также попробовал весь "FlexClient.getInstance (). Id = null;" вещь тоже, и она не работала сама по себе , но это было как и где Я реализовал это, что заставило его работать.

Итак, это то, что I сделал, чтобы решить эту проблему.

В моей основной форме, до ЛЮБОГО вызовов RemoteServer, я установил обработчик creationComplete и поместил этот код, который вы уже знаете и любите:

// Not sure if this is needed anymore, but I'm leaving it in
FlexClient.getInstance().id = null;

Затем, в моем самом первом вызове на сервер, я корректно обработал ошибку и снова удалил этот вонючий идентификатор:

    public function login(event:Event): void {

        Swiz.executeServiceCall(roUsers.login(),
            function (event:ResultEvent): void {
                // Handle a successful login here...
            }
            , function (faultevent:FaultEvent): void {
                // This code fixes this issue with IE tabs dying and leaving Flex with a Duplicate Session problem.
                if (faultevent.fault.faultString.indexOf("duplicate")) {
                  FlexClient.getInstance().id = null;
                  Swiz.dispatchEvent(event);
                }
        });

    }

И это сработало .

По сути, попробуйте выполнить вызов, и если он не удастся выполнить дубликат сеанса, очистите этот идентификатор и повторите вызов.

Ключевым моментом является то, что Я не думаю, что очистка идентификатора работает, пока вы не сделаете хотя бы один звонок на сервер . Как только вы это сделаете, это сработало как ШАРМ для меня, и в всех моих приложений.

Обратите внимание, что я использую описанную выше инфраструктуру SWIZ, поэтому просто переведите ее в свой мир.

Кстати, я никогда не видел этой ошибки ни в одном другом браузере, кроме IE, и я верю в это может как-то связано с печально известной проблемой Dead Tab, от которой страдает IE.

Если вышеперечисленное не работает, я также знаю несколько изменений в некоторых конфигурационных файлах на сервере, которые могут помочь.

Удачи, мой друг!

0 голосов
/ 02 сентября 2014

Дополнительная, не связанная, причина, о которой следует знать;

Некоторые браузеры (например, Internet Explorer) применяют правила именования доменов к файлам cookie, а это означает, что кодовый домен, такой как "my_clientX.server.com", хотя он может возвращать действительные ответы BlazeDS, он будет постоянно запускать дубликаты уведомлений о сеансе, поскольку доступ к cookie будет заблокирован.

Изменение имени на действительное имя (без подчеркивания) решит проблему.

0 голосов
/ 21 ноября 2011

Эта статья под названием Предотвращение повторяющихся ошибок сеанса в LCDS дает подробное объяснение того, что происходит в вашей ситуации.Вот соответствующая цитата:

... [LCDS] считает, что FlexClient, от которого он получил запрос, уже был связан с другим сеансом на сервере.

Для клиентаЧтобы убедиться, что FlexClients в приложении не перешли в это плохое состояние, клиентское приложение должно убедиться, что сеанс уже установлен на сервере, прежде чем несколько FlexClients подключатся к серверу одновременно.

Существует несколько подходов, рекомендуемых для исправления этой проблемы, в том числе:

  • вызов страницы jsp для загрузки приложения
    "The jsp page could both create a session for the client application and return an html wrapper to the client which would load the swf."
  • вызов пункта назначения Remoting
    "which would automatically create a session for the client application on the server"
...