Я поискал в Интернете, пытаясь найти кого-нибудь, кто мог бы столкнуться с этой проблемой, но пришел с пустыми руками. Итак, вот и:
У нас есть веб-приложение на Java (на основе Spring MVC 4). Он стоит за Microsoft IIS, выступая в качестве балансировщика нагрузки / обратного прокси-сервера с использованием маршрутизации запросов приложений (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 10Cache-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
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 10Cache-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
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
включает заголовок Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15
, а ответ dev
- нет.
Я включил «Отслеживание неудачных запросов» в IIS для отладки ответа 101
и вижу, что некоторые заголовки перезаписываются IIS, а именно заголовок Sec-WebSocket-Accept
.
IIS также показывает, что этот запрос создает 502.5
ошибку. Я поискал это и нашел следующее: https://support.microsoft.com/en-us/kb/943891, в котором говорится, что 502.5
это «сбой WebSocket (ARR)», и это все, что в нем говорится. Как ни странно, Chrome Dev Tools показывает, что он отвечает 101, как и предполагалось ...
Я пробовал все это с локальным сервером приложений (Tomcat 8 без IIS), и веб-сокеты работали нормально. 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 в OS X не работают.
Обновление 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
-Dorg.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS=true
, которая должна была выполнить трюк в соответствии с документами:If true, disable all built-in extensions provided by the server, such as message compression.
, но, похоже, она вообще не изменила заголовки ответов - person Will Warren   schedule 06.02.2016