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.

взгляните на это статья.

https://community.home-assistant.io/t/solved-access-via-iis-reverse-proxy-died-after-upgrade-to-0-58/34408

Это сработало для меня.

после изменений заголовок был переопределен пустым значением в моем входящем правиле перезаписи, и ARR не имел проблем с обработкой запросов и ответов Websocket, потому что они не были сжаты этим, и ARR мог обрабатывать их с помощью активированного модуля Websockets в IIS.


У нас была такая же проблема с прокси-сервером приложения Azure AD перед Tomcat. Нам пришлось отключить расширения Sec-WebSocket в Tomcat.