У меня есть стек 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.
}