我已经在互联网上搜寻,试图找到任何可能遇到此问题但空手而归的人。所以这里:
我们有一个java Web应用程序(基于Spring MVC 4)。它位于Microsoft IIS后面,充当使用应用程序请求路由(ARR)v3的负载均衡器/反向代理。
此IIS正在针对3种不同的环境(均运行相同的 Java代码)与ARR执行负载平衡:dev.example.com
,demo.example.com
和qa.example.com
。< / p>
该应用程序向用户提供通知&#39;通过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
响应则没有。
我开启了#34;失败的请求跟踪&#34;在IIS上调试101
响应,我可以看到有一些标题被IIS覆盖 - Sec-WebSocket-Accept
标题即为。
IIS还显示该请求正在创建502.5
错误。我查了一下,发现了这个:https://support.microsoft.com/en-us/kb/943891表示502.5
是&#34; WebSocket失败(ARR)&#34;它就是这么说的。奇怪的是,Chrome开发工具显示它响应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: websocket
和Connection: upgrade
在我的本地服务器上是小写,而当您将IIS放在前面时,它是Websocket
和Upgrade
。
Sec-WebSocket-Extensions
在qa
之后的permessage-deflate;
中也有一个尾随空格,但本地没有。
在Microsoft Edge(Windows 10)的qa
环境中,一切正常。我还没有尝试过Internet Explorer 11,但我必须假设它可能也有效。 OSX上的Firefox和Chrome不起作用。
在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
答案 0 :(得分:2)
我已经发现了解决方案,尽管它并不像我希望的那样令人满意。
在我们的项目pom.xml
中,我们spring-core:4.2.5
但spring-websocket
和spring-messaging
为4.1.6
。版本不匹配导致了一些问题。
当版本不匹配时,在Tomcat启动选项中设置-Dorg.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS=true
无效。当版本相同时,设置该JVM选项按预期工作。
101
响应现在不包含permessage-deflate
,并且websockets能够通过IIS连接没有问题。我们的应用程序不会通过套接字发送大量数据,因此我们可以进行权衡。
答案 1 :(得分:2)
使用ARR3在Tomcat7和IIS8上出现同样的问题。我们没有使用Spring库。
如果启用了websocket-extensiones,则在建立websocket连接后不会发送任何帧。但是,如果我们禁用websocket-extensions,那么一切都完美无缺。
答案 2 :(得分:2)
我遇到了同样的问题。 解决方法是使用ARR覆盖客户端的Websockets压缩处理标头。 IE不会强制或尝试使用Websocket压缩,但是Chrome和Firefox会发出带有标题“ Sec-WebSocket-Extensions:permessage-deflate”的请求。
由于我无法影响NodeJS后端服务器,因此必须在ARR中解决此问题。
看看这篇文章。
对我有用。
在修改之后,我的入站重写规则中的标头被覆盖为空值,并且ARR处理Websocket请求和响应没有问题,因为它们没有被此压缩,并且ARR可以使用IIS中激活的Websockets模块来处理它们。
答案 3 :(得分:-1)
我们在Tomcat前面的Azure AD应用程序代理遇到了相同的问题。我们必须在Tomcat中禁用Sec-WebSocket-Extensions。