Websockets на Tomcat 8 + IIS 8 с ARR 3 не работают
я рыскал в интернете, пытаясь найти кого-нибудь, кто может испытывать эту проблему, но прийти с пустыми руками. Так вот:
у нас есть веб-приложение java (на основе Spring MVC 4). Он сидит за Microsoft IIS, действуя как балансировщик нагрузки / обратный прокси-сервер, используя Application Request Routing (ARR) v3.
этот IIS выполняет балансировку нагрузки с ARR для 3 различных сред (все запущенные то же самое Java-код): dev.example.com
, demo.example.com
и qa.example.com
.
приложение обслуживает уведомления браузеров пользователей с помощью WebSockets через SockJS и stompjs, и все это работает хорошо, пока серверы приложений были на Tomcat 7. После обновления qa.example.com
среда для Tomcat 8, соединения WebSocket перестали работать - он возвращается к запросам XHR POST.
я хочу подчеркнуть, что никаких изменений в IIS не было сделано, только qa
сервер приложений.
вот пример запрос/ответ от dev
среды (рабочая):
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cache-Control: no-cache
Connection: Upgrade
Cookie: <cookies snipped>
Host: dev.example.com
Origin: https://dev.example.com
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: E7aIek0X6qcO9PAl1n6w4Q==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36
ответ
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: Upgrade
Date: Thu, 22 Oct 2015 02:19:35 GMT
Expires: 0
Pragma: no-cache
Sec-WebSocket-Accept: dKYK05s4eP87iA20aSo/3ntOrPU=
Server: Microsoft-IIS/8.0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Upgrade: Websocket
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Powered-By: ARR/3.0
X-XSS-Protection: 1; mode=block
вот пример запроса / ответа от qa
окружающая среда (сломанная):
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cache-Control: no-cache
Connection: Upgrade
Cookie: <cookies snipped>
Host: qa.example.com
Origin: https://qa.example.com
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: jTOIAT0+o35+Qi0ZWh2gyQ==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36
ответ:
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: Upgrade
Date: Thu, 22 Oct 2015 02:18:30 GMT
Expires: 0
Pragma: no-cache
Sec-WebSocket-Accept: P+fEH8pvxcu3sEoO5fDizjSbwJc=
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
Server: Microsoft-IIS/8.0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Upgrade: Websocket
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Powered-By: ARR/3.0
X-XSS-Protection: 1; mode=block
единственное очевидное различие заключается в том, что qa
ответ включает в себя С dev
ответ нет.
я включил "трассировку неудачного запроса" в IIS для отладки 101
ответ, и я вижу, что есть некоторые заголовки, которые перезаписываются IIS - а именно.
IIS также показывает, что этот запрос создает 502.5
ошибка. Я посмотрел вверх и нашел это: https://support.microsoft.com/en-us/kb/943891 в котором говорится, что 502.5
это " сбой WebSocket (ARR)", и это все, что он говорит. Как ни странно, Chrome Dev Tools показывает, что он отвечает 101 так же, как и предполагалось к...
я пробовал все это с локальным сервером приложений (Tomcat 8 без IIS), и websockets работал просто отлично. Tomcat 7 + IIS + ARR + WebSockets работает просто отлично. Tomcat 8 + IIS + ARR + WebSockets не делает.
моя точная версия Tomcat 8-8.0.28-но я получил те же результаты на Tomcat 8.0.26.
мой следующий шаг-продолжать понижать Tomcat 8 через второстепенные версии и посмотреть, изменится ли что-нибудь. Я обновлю здесь, Если я обнаружу что угодно.
обновление
вот ответ от моего локального сервера (без IIS):
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Connection: upgrade
Date: Thu, 22 Oct 2015 13:59:23 GMT
Expires: 0
Pragma: no-cache
Sec-WebSocket-Accept: 718HnPxHN8crYYzNGFjQf7w8O+Y=
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
Server: Apache-Coyote/1.1
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
Upgrade: websocket
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
это очень похоже на сломанный qa
запрос, но он отлично работает. Так что я думаю Sec-WebSocket-Extensions
дело было в отвлекающем маневре. Также Upgrade: websocket
и Connection: upgrade
ниже случае на моем локальном сервере, тогда как Websocket
и Upgrade
когда вы ставите IIS впереди.
Sec-WebSocket-Extensions
также имеет конечное пространство в qa
после permessage-deflate;
но местные не не.
обновление 2
все отлично работает на qa
среда в Microsoft Edge (Windows 10) я не пробовал Internet Explorer 11, но я должен предположить, что он, вероятно, также работает. Firefox и Chrome на OSX не работают.
обновление 3
запрос от Tomcat, прежде чем он будет изменен IIS/ARR:
HTTP/1.1 101 Switching Protocols
Server: Apache-Coyote/1.1
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: luP49lroNK9qTdaNNnSCLXnxAWc=
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
Date: Tue, 27 Oct 2015 21:10:48 GMT
4 ответов
в нашем проекте pom.xml
У нас spring-core:4.2.5
но spring-websocket
и spring-messaging
были 4.1.6
. Несоответствие версий явно вызывало некоторые проблемы.
задание -Dorg.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS=true
в параметрах запуска Tomcat, когда версии были несовпадающие не было никакого эффекта. Установка этой опции JVM, когда версии были тот же работал, как ожидалось.
в 101
ответ теперь не содержит permessage-deflate
и websockets могут подключаться без проблем через IIS. Наше приложение не отправляет много данных через сокеты, поэтому мы были в порядке, делая этот компромисс.
та же проблема на Tomcat7 и IIS8 с использованием ARR3. Мы не используем библиотеки Spring.
не пересылаются после соединение установлено, если с WebSocket-extensiones включены. Но если мы отключили WebSocket-расширения, то все работает отлично.
У меня была та же проблема. Обходным путем является переопределение заголовка обработки сжатия Websockets от клиента с помощью ARR. IE не может принудительно или попробовать сжатие Websocket, но Chrome и Firefox выдадут запрос с заголовком "Sec-WebSocket-Extensions: permessage-deflate".
поскольку я не мог повлиять на свой сервер NodeJS, мне пришлось решить это в ARR.
взгляните на это статья.
Это сработало для меня.
после изменений заголовок был переопределен пустым значением в моем входящем правиле перезаписи, и ARR не имел проблем с обработкой запросов и ответов Websocket, потому что они не были сжаты этим, и ARR мог обрабатывать их с помощью активированного модуля Websockets в IIS.
У нас была такая же проблема с прокси-сервером приложения Azure AD перед Tomcat. Нам пришлось отключить расширения Sec-WebSocket в Tomcat.