LCDS & Flex - Предотвращение ошибок DuplicateHTTPSession после выхода из системы

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

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

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

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

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

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

В результате получена ошибка следующего вида:

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

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

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

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


Обновлять

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

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

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

Мой сценарий отличается, потому что JSession (и связанные объекты LCDS FlexSession / Client-Side 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.
   }

person Marty Pitt    schedule 18.11.2011    source источник
comment
Вы можете прислать мне отдельный проект, в котором воспроизводится эта проблема?   -  person Cornel Creanga    schedule 22.11.2011
comment
Хотел бы я добавить к щедрости. У меня тоже есть эта проблема. Наше приложение использует BlazeDS внутри веб-сервера Jetty. Часто я вижу это, когда пользователь запускает два экземпляра приложения (скажем, один на порту 80 и один на порту 81). Если вы откроете оба экземпляра в одном браузере, произойдет исключение, но если вы откроете их в разных браузерах, все будет в порядке. Это также может происходить (не удалось проверить) при запуске другого веб-сервера на локальном хосте, который использует файл cookie jsessionid.   -  person sean    schedule 22.11.2011


Ответы (3)


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

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

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

Итак, вот что сделал я, и проблема исчезла.

В моей основной форме, перед выполнением ЛЮБЫХ вызовов 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.

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

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

person PRB    schedule 22.11.2011

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

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

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

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

  • вызов страницы 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."
  • вызов пункта назначения удаленного взаимодействия
    "which would automatically create a session for the client application on the server"
person gMale    schedule 21.11.2011
comment
Спасибо за ответ. К сожалению, я уже читал эту статью, и обсуждаемые в ней техники не работают в моем исследовании. Я обновил свой вопрос, подробно объяснив, почему я считаю, что эти решения не работают (для меня). - person Marty Pitt; 22.11.2011

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

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

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

person Gaius Coffey    schedule 02.09.2014