我有一个 meteor 应用程序的apache代理,并且apache和meteor分别位于两台机器上。我需要这种方式,因为apache必须服务于许多真实的网站,并且由于资源有限,在这台机器上安装 meteor 应用程序不是一个好主意。
但是,如果我尝试通过代理从外部连接,则WebSocket握手失败,响应代码为400“只能升级到websocket”。当我从LAN内部直接连接到 meteor 机器时,一切正常。
当WebSocket失败时,SockJS/Meteor会退回到XHR,但是不幸的是,这会引起应用程序中的一些错误。因此,在大多数情况下,我确实需要WebSocket才能工作。
我用这里提到的补丁修补了apache的安装过程:https://stackoverflow.com/a/16998664
看起来一切顺利,但是什么都没有改变...
我的apache代理指令当前如下:
ProxyRequests Off
ProxyPreserveHost On
ModPagespeed Off
<proxy>
Order deny,allow
Allow from all
</proxy>
ProxyPass / http://10.0.2.6:3000/
ProxyPassReverse / http://10.0.2.6:3000/
我什至知道是什么引发了问题。 Apache代理将 header 弄乱了。有问题的数据包离开我的机器的原始请求 header 如下所示:
GET /sockjs/430/minw4r_o/websocket HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: myKey
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
User-Agent: My Agent
像这样从apache代理转发数据包时:
GET /sockjs/430/minw4r_o/websocket HTTP/1.1
Host: example.com
Origin: http://example.com
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: myKey
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
User-Agent: My Agent
X-Forwarded-For: 24.xxx.xxx.xxx
X-Forwarded-Host: example.com
X-Forwarded-Server: example.com
Connection: Keep-Alive
因此,“升级”被删除,“连接”被更改,因此websocket握手失败。现在,我可以尝试始终使用RequestHeader指令将“Upgrade”设置为“websocket”。但是,这感觉不对,我想这还会带来其他问题,所以我想知道是否有针对此问题的真正解决方案?还是这是https://stackoverflow.com/a/16998664的补丁程序应该解决的问题,而在我应用它的那端出了点问题?
从我读到的内容来看,切换到nginx可以使此设置更容易。我会考虑的,但是在可能的情况下,我想用apache来做,因为nginx会使其他事情变得更加复杂,并花费我很多时间。
最佳答案
我们将其用于Apache和Apache背后的SockJS应用程序。 Apache正在自动执行WebSocket代理,但是您必须将方案重写为ws,否则会回退到XHR。但仅当连接是WebSocket握手时。添加以下内容将解决您的问题:)(注意:将localhost:3000
相应地更改为您自己的后端URL。
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^websocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade [NC]
RewriteRule .* ws://localhost:3000%{REQUEST_URI} [P]
关于apache - 如何为Meteor/SockJS和WebSocket设置一个Apache代理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22002744/