Tomcat 8 + IIS 8与arr3的Websockets不工作



我已经在网上搜索了,试图找到任何可能遇到这个问题的人,但两手空空。这里是:

我们有一个java web应用程序(基于Spring MVC 4),它位于Microsoft IIS后面,使用应用请求路由(ARR) v3作为负载均衡器/反向代理。

这个IIS在3个不同的环境中使用ARR执行负载平衡(所有运行相同的)Java代码):dev.example.com,demo.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/943891它说502.5是"WebSocket失败(ARR)",这就是它所说的。奇怪的是,Chrome开发工具显示它的响应是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: websocketConnection: upgrade在我的本地服务器上是小写的,而当你把IIS放在前面时,它是WebsocketUpgrade

Sec-WebSocket-Extensionsqapermessage-deflate;后面也有一个尾随空格,但本地没有。

<标题>更新2 h1> Microsoft Edge (Windows 10)的qa环境下都可以正常工作。我没有尝试过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

我已经发现了解决方案,尽管它不像我希望的那样令人满意。

在我们的项目pom.xml中,我们有spring-core:4.2.5,但spring-websocketspring-messaging4.1.6。版本不匹配显然导致了一些问题。

版本不匹配时,在Tomcat启动选项中设置-Dorg.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS=true没有效果。当版本相同时设置JVM选项按预期工作

101响应现在不包含permessage-deflate和websockets能够通过IIS连接没有问题。我们的应用程序不会通过套接字发送大量数据,所以我们可以进行这种权衡。

我也有同样的问题。解决方法是用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-extensiones被启用,在websocket连接建立后不发送帧。但是如果我们禁用websocket扩展,那么一切都可以正常工作。

我们在Tomcat前面的Azure AD应用程序代理中遇到了同样的问题。我们必须在Tomcat中禁用Sec-WebSocket-Extensions。

相关内容

  • 没有找到相关文章

最新更新