簡體   English   中英

帶有 ARR 3 的 Tomcat 8 + IIS 8 上的 Websocket 不工作

[英]Websockets on Tomcat 8 + IIS 8 with ARR 3 are not working

我已經在互聯網上搜索,試圖找到任何可能遇到此問題但空手而歸的人。 所以這里是:

我們有一個 Java Web 應用程序(基於 Spring MVC 4)。 它位於 Microsoft IIS 之后,充當負載平衡器/反向代理,使用應用程序請求路由 (ARR) v3。

這個 IIS 正在使用 ARR 為 3 個不同的環境(都運行相同的Java 代碼)執行負載平衡: dev.example.comdemo.example.comqa.example.com

該應用程序通過 SockJS 和 stompjs 使用 WebSockets 向用戶的瀏覽器提供通知,當應用程序服務器在 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響應包含一個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/943891502.5是“WebSocket 失敗(ARR)”,這就是它所說的。 奇怪的是,Chrome Dev Tools 顯示它以 101 響應,就像它應該的那樣......

我在本地應用程序服務器(沒有 IIS 的 Tomcat 8)上嘗試了這一切,並且 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: websocketConnection: upgrade在我的本地服務器上是小寫的,而當您將 IIS 放在前面時,它是WebsocketUpgrade

Sec-WebSocket-Extensionspermessage-deflate;之后在qa也有一個尾隨空格permessage-deflate; 但當地沒有。

更新 2

在 Microsoft Edge (Windows 10) 的qa環境中一切正常我沒有嘗試過 Internet Explorer 11,但我必須假設它可能也有效。 OSX 上的 Firefox 和 Chrome 不起作用。

更新 3

在被 IIS/ARR 修改之前從 Tomcat 請求:

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

我已經找到了解決方案,盡管它並不像我希望的那樣令人滿意。

在我們項目的pom.xml我們有spring-core:4.2.5spring-websocketspring-messaging4.1.6 版本不匹配顯然導致了一些問題。

當版本不匹配時,在 Tomcat 啟動選項中設置-Dorg.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS=true無效。 在版本與預期相同時設置該 JVM 選項。

101響應現在不包含permessage-deflate並且 websockets 能夠通過 IIS permessage-deflate地連接。 我們的應用程序不會通過套接字發送大量數據,因此我們可以進行這種權衡。

我有同樣的問題。 解決方法是使用 ARR 覆蓋來自客戶端的 Websockets 壓縮處理標頭。 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

它對我有用。

在修改之后,我的入站重寫規則中的 Header 被一個空白值覆蓋,並且 ARR 沒有問題來處理 Websocket 請求和響應,因為它們沒有被壓縮,並且 ARR 可以使用 IIS 中激活的 Websockets 模塊處理它們。

在使用 ARR3 的 Tomcat7 和 IIS8 上存在同樣的問題。 我們沒有使用 Spring 庫。

如果啟用了 websocket 擴展,則在建立 websocket 連接后不會發送任何幀。 但是如果我們禁用了 websocket-extensions,那么一切都會完美運行。

我們在 Tomcat 前面的 Azure AD 應用程序代理也遇到了同樣的問題。 我們不得不在 Tomcat 中禁用 Sec-WebSocket-Extensions。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM