Сценарий:
- Пользователь использует IE9 (IE8/10 не затрагивается).
- У пользователя есть активная сессия.
- Страница запускает запрос AJAX POST (GET не затрагивается) к контроллеру с атрибутом
SessionState(SessionStateBehavior.Required)
(ReadOnly
не затрагивается). Что-то препятствует немедленной обработке этого запроса (например, другой выполняемый запрос, который заблокировал сеанс). - Пока выполняется AJAX POST, пользователь уходит со страницы (GET или POST - не имеет значения)
Результат:
- AJAX POST завершается и возвращает HTTP 500 (который браузер с тех пор перестал прослушивать, но вы можете увидеть его в журналах IIS). IIS Failed Request Tracing показывает ошибку: «Указанное сетевое имя больше недоступно. (0x80070040)».
- Сеанс пользователя блокируется где-то между 80 и 120 секундами (обычно около 100), прежде чем может быть выполнен следующий запрос, требующий доступа к сеансу чтения/записи.
Дальнейшее изучение журнала, созданного трассировкой невыполненных запросов IIS, показывает, что AJAX POST дает сбой, подобный этому, после состояния сеанса заблокировано (во время фазы REQUEST_ACQUIRE_STATE
), но поскольку фаза REQUEST_RELEASE_STATE
не происходит, блокировка сеанса не снимается. Я предполагаю, что в игре есть какой-то механизм безопасности, который разблокирует сеанс через 80-120 секунд, но это очень долгое зависание явно нежелательно для моих пользователей.
У меня есть простой проект VS2012/.Net 4.5/MVC4, демонстрирующий проблему, доступную по адресу https://github.com/jorupp/Ie9SessionCrash. (есть одна страница, которая делает серию сообщений о действиях со спящими вызовами). Трассировка невыполненных запросов IIS, показывающая проблему, находится в проекте по адресу https://github.com/jorupp/Ie9SessionCrash/tree/master/Ie9SessionCrash/TraceOfHttp500.
Чтобы обойти эту проблему, мы планируем никогда не выполнять вызовы AJAX POST для действий, требующих сеанса, а также:
- Использование вызовов GET, где это возможно
- Использование POST-вызовов для контроллеров с атрибутом
SessionState(SessionStateBehavior.ReadOnly)
.
Есть ли лучший способ справиться с этим, или мне не хватает патча IIS/.Net в связи с этим? Или этот сценарий недействителен по какой-то другой причине? Я не решаюсь винить в этом фреймворк/IIS, но я думаю, что устранил ошибку моего кода.