当前位置:  开发笔记 > 程序员 > 正文

IIS 8中的Websockets反向代理

如何解决《IIS8中的Websockets反向代理》经验,为你挑选了2个好方法。

我正在尝试通过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中的一般示例规则:


                    
         
          
            
           
                 
        
     

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

最终目标是合并noVNC/websockify,以便为网络上的多个VNC服务器提供基于浏览器的客户端访问.任何帮助理解如何反向代理websockets表示赞赏.



1> jowo..:

我一直在尝试使用ARR 3.0在IIS 8.5上完成同样的事情,并最终发现了问题.根据微软的Erez Benari的说法,这是可能的:

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);

随着一个简单的测试页面:

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

然后,我在本地计算机上设置了ARR反向代理,并在localhost上的"wstest"目录的web.config文件中添加以下代码:




    
        
            
                
                
                    
                
                
            
        
    


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

Chrome发送:

GET ws://localhost/wstest HTTP/1.1
Host: localhost
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: file://
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Sec-WebSocket-Key: 4ufu8nAOj7cKndASs4EX9w==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

Node.js服务器收到:

cache-control: no-cache
connection: upgrade
pragma: no-cache
upgrade: Websocket
accept-encoding: gzip, deflate, sdch
accept-language: en-US,en;q=0.8
host: localhost:3011
max-forwards: 10
user-agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36
origin: file://
sec-websocket-version: 13
sec-websocket-key: fBkTwAS9d/unXYKDE3+Jjg==
sec-websocket-extensions: permessage-deflate; client_max_window_bits
x-original-url: /wstest
x-forwarded-for: [::1]:54499
x-arr-log-id: a0b27458-9231-491d-b74b-07ae5a01c300

Node.js服务器响应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-Websocket-Accept: yep8mgQACAc93oGIk8Azde4WSXk=
Sec-WebSocket-Extensions: permessage-deflate

最后Chrome收到:

HTTP/1.1 101 Switching Protocols
Upgrade: Websocket
Sec-WebSocket-Accept: CBSM8dzuDoDG0OrJC28nIqaw/sI=
Sec-WebSocket-Extensions: permessage-deflate
X-Powered-By: ARR/3.0
Connection: Upgrade
X-Powered-By: ASP.NET
Date: Fri, 10 Jun 2016 21:16:16 GMT
EndTime: 17:16:16.148
ReceivedBytes: 0
SentBytes: 0

所以现在他们已经联系了.这一切看起来都不错,唯一明显的区别是Sec-WebSocket-Key和Sec-WebSocket-Accept由IIS或ARR代理在两个方向上都进行了更改.

但是......没有任何WebSocket框架可以通过代理!当Chrome收到有关其升级请求的正面反馈时,它会发送其WebSocket消息帧,然后它会坐下来等待来自服务器的消息.Node.js服务器发送其帧,并且不会发生错误,但Chrome从未接收过它们.Node.js从未收到Chrome发送的消息.似乎ARR/IIS正在向两个方向丢弃WebSocket帧.

请注意Chrome如何告诉服务器它支持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能够通过在自身和客户端之间进行协商来正确处理扩展,然后在自身和服务器之间进行单独的协商.就目前而言,它只是让客户端和服务器相互协商,从而导致此错误.


我正在使用带有ARR 3.0的Server 2016上的IIS 10和(曾经了解到我需要安装Websockets功能)我正在使用https(包括渗透 - 放气)在代理到chrome之间进行双向websocket通信Sec-Websocket-Extentions中的扩展.我没有完全尝试你的测试(因为我正在测试我自己的应用程序)但它似乎工作.也许在IIS 10中修复了?

2> 小智..:

如@jowo所述,IIS8 / 8.5似乎不支持Sec-Websocket-Extensions。话虽如此,我应用的解决方法是简单地重写有问题的服务器变量。首先将HTTP_SEC_WEBSOCKET_EXTENSIONS添加到允许的服务器变量列表中,然后将其添加到您的规则中:

这样,目的地就不会收到麻烦的permessage-deflate :)

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有