gpt4 book ai didi

iis - IIS 8中的Websockets反向代理

转载 作者:行者123 更新时间:2023-12-04 00:21:00 44 4
gpt4 key购买 nike

我正在尝试通过IIS上的反向代理连接到websockets服务器(websockify)。 IIS和Websockets服务器位于同一台物理服务器上(Windows Server 2012 R2,IIS 8.5,ARR 3,启用了Websockets)。我已经看到了一些有关此的问题,建议将其与IIS 8和ARR 3配合使用,但尚无实际解决方案。我在IIS中使用http / https反向代理有一些经验,但这是我第一次尝试使用websockets。

例如:

原始网址:
ws://10.2.1.10/websockify

反向代理需要将其转换为:
ws://10.2.1.10:5901 / websockify

web.config中过于笼统的示例规则:

<rewrite>
<rules>
<rule name="WS reverse proxy" stopProcessing="true">
<match url="(.*)" />
<conditions> <add input="{CACHE_URL}" pattern="^(.+)://" />
</conditions>
<action type="Rewrite" url="{C:1}://10.2.1.10:5901/websockify"/>
</rule>
</rules>
</rewrite>


根据失败的请求跟踪,URL似乎已被翻译,但由于某种原因,它未到达10.2.1.10:5901的websocket服务器。

最终目标是合并noVNC / websockify,以提供基于浏览器的客户端访问网络上的多个VNC服务器。感谢您对理解如何反向代理WebSocket的任何帮助。

最佳答案

我一直试图在具有ARR 3.0的IIS 8.5上完成同样的事情,最终发现了问题。根据Microsoft的Erez Benari,this is possible


WebSocket支持需要在IIS上安装WebSocket功能,但不需要任何其他配置或操作。使用“服务器管理器添加角色和功能”安装功能,完成后,ARR 3.0将适当地处理请求。


作为测试,我为WebSocket设置了一个Node.js服务器:

const WebSocketServer = require('ws');const wss = new WebSocketServer({ port: 3011 });function sendWSMessage(msg) {    wss.clients.forEach((client) => {        client.send(msg);    });}setInterval(function() {    sendWSMessage('hello client');}, 3000);

Along with a simple test page:

var websock = new WebSocket('ws://localhost:3011');websock.onmessage = function (event) {    console.log(event.data);};websock.onopen = function (event) {  websock.send("hello server"); };

Then, I set up an ARR reverse proxy on my local machine, with the following in a web.config file of a "wstest" directory on localhost:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="WebSocketTestRule" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{CACHE_URL}" pattern="^(.+)://" />
</conditions>
<action type="Rewrite" url="{C:1}://localhost:3011/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>


这应该将 //localhost/wstest的所有流量转发到端口3011上的Node.js服务器。当我通过 ws://localhost:3011直接连接到Node.js服务器时,Node服务器即可工作。当我尝试通过 ws://localhost/wstest通过代理连接时,请求将其连接到Node.js服务器,然后进行升级并建立连接。

Chrome发送:

GET ws:// localhost / wstest HTTP / 1.1
主机:localhost
连接:升级
语法:无缓存
缓存控制:无缓存
升级:websocket
来源:file://
安全WebSocket版本:13
用户代理:Mozilla / 5.0(Windows NT 6.3; WOW64)AppleWebKit / 537.36(KHTML,例如Gecko)Chrome / 51.0.2704.84 Safari / 537.36
接受编码:gzip,deflate,sdch
接受语言:en-US,en; q = 0.8
Sec-WebSocket-密钥:4ufu8nAOj7cKndASs4EX9w ==
Sec-WebSocket-Extensions:permessage-deflate; client_max_window_bits


Node.js服务器收到:

缓存控制:无缓存
连接方式:升级
语用:无缓存
升级:Websocket
接受编码:gzip,deflate,sdch
接受语言:en-US,en; q = 0.8
主机:localhost:3011
最大前进:10
用户代理:Mozilla / 5.0(Windows NT 6.3; WOW64)AppleWebKit / 537.36(KHTML,如Gecko)Chrome / 51.0.2704.84 Safari / 537.36
来源:file://
sec-websocket-version:13
sec-websocket-key:fBkTwAS9d / unXYKDE3 + Jjg ==
sec-websocket-extensions:permessage-deflate; client_max_window_bits
x-原始网址:/ wstest
x-forward-for:[:: 1]:54499
x-arr-log-id:a0b27458-9231-491d-b74b-07ae5a01c300


Node.js服务器响应:

HTTP / 1.1 101交换协议
升级:websocket
连接:升级
Sec-Websocket-Accept:yep8mgQACAc93oGIk8Azde4WSXk =
Sec-WebSocket-扩展:permessage-deflate


最后,Chrome收到:

HTTP / 1.1 101交换协议
升级:Websocket
Sec-WebSocket-接受:CBSM8dzuDoDG0OrJC28nIqaw / sI =
Sec-WebSocket-扩展:permessage-deflate
X-Powered-By:ARR / 3.0
连接:升级
X-Powered-by:ASP.NET
日期:2016年6月10日,星期五,21:16:16 GMT
结束时间:17:16:16.148
ReceivedBytes:0
已发送字节:0


因此,现在它们已连接。这一切看起来都不错,唯一明显的区别是IIS或ARR代理在两个方向上都更改了Sec-WebSocket-Key和Sec-WebSocket-Accept。

但是...没有WebSocket框架通过代理实现!当Chrome收到有关其升级请求的积极反馈时,它会发送其WebSocket消息帧,然后坐着等待来自服务器的消息。 Node.js服务器发送其框架,并且没有发生错误,但Chrome从未收到它们。 Chrome发送的消息永远不会被Node.js接收。看来ARR / IIS正在双向丢弃WebSocket框架。

请注意,Chrome如何告知服务器它支持permessage-deflate扩展,permessage-deflate扩展是用于按消息压缩的WebSocket扩展。服务器正在响应它还支持permessage-deflate,因此当浏览器和服务器相互发送消息时,他们将使用此压缩扩展。但是,中间那个人,ARR,显然不支持这种压缩!通过关闭服务器上对permessage-deflate的支持,实际的WebSocket框架现在可以完美地通过代理了:

const wss = new WebSocketServer({port:3011,perMessageDeflate:false});


我认为问题在于ARR 3.0不支持 Sec-Websocket-Extensions标头,因此允许标头简单地通过。但是,允许该标头在客户端和服务器之间进行协商是错误的,因为ARR不参与协商,也无法告诉两方它不支持传递压缩消息。希望有一天,ARR将能够通过自身与客户端之间的协商,然后在自身与服务器之间进行单独的协商,来正确处理扩展。就目前而言,它只是让客户端和服务器相互协商,从而导致此错误。

关于iis - IIS 8中的Websockets反向代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34316825/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com