我正在使用带有mod_proxy
模块的 Apache 将我的 Node.js 应用程序反向代理到端口 80,以便我们可以将其作为内部的应用。
我有一个文件,sites-enabled
其中包含以下内容:
VirtualHost *:80>
DocumentRoot /var/www/internal/
ServerName internal
ServerAlias internal
<Directory /var/www/internal/public/>
Options All
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ProxyRequests off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ retry=0
ProxyPassReverse / http://localhost:8080/
ProxyPreserveHost on
ProxyTimeout 1200
LogLevel debug
AllowEncodedSlashes on
</VirtualHost>
正如我所说,我们的应用程序是用 Node.js 编写的,我们正在使用socket.io使用 web-sockets,因为我们的应用程序也包含实时元素。问题是,它mod_proxy
似乎无法处理 web 套接字,我们在尝试使用它们时会收到错误:
WebSocket connection to 'ws://bloot/socket.io/1/websocket/nHtTh6ZwQjSXlmI7UMua' failed: Unexpected response code: 502
ip:port
我们如何才能解决这个问题并让套接字继续工作,因为目前我们唯一能让它工作的方式是通过我们不想访问的网站。
另外,顺便问一下,我该如何才能ErrorDocument
正常工作?我们的错误文件存储在,/var/www/internal/public/error/
但它们似乎也通过代理发送了?
答案1
在 Apache 2.2 中,反向代理不支持 Web 套接字,但我猜 Apache 2.4 有。您有三个选项可以解决此问题。
1)升级到 2.4
2) 您可以使用轮询 (xhr-polling) 代替 Web 套接字。您需要做的就是在服务器端 Node.js 代码中配置传输方法,如下所示。
var io = require('socket.io').listen(PORT);
io.configure(function () {
io.set("transports", ["xhr-polling"]);
});
这样,socket.io 就不会尝试找出最佳传输方法。它将直接使用 xhr-polling,这是一种基于 Ajax 的轮询,可以在每个浏览器和 Web 服务器上正常运行,不会出现任何问题。
3) 如果您仍想使用 Web 套接字,您可以重新编译 Apache 2.2 以支持 Web 套接字。有关详细信息,请查看此文章: http://blog.cafarelli.fr/post/2013/04/26/Backporting-Apache-support-for-websockets-reverse-proxy-%28aka-getting-GateOne-to-work-behind-Apache%29