正如标题所示,我正在尝试让 Apache 和 Socket.io (node.js) 很好地发挥作用,尤其是在 SSL 上。目前,位于 https://www.example.com 的客户端应用程序使用 Socket.io over SSL 连接到位于 [SSL 协议]://socket.example.com/socket.io/?query_stuff 的服务器*。与 wss:// 的连接总是失败,因此 Socket.io 降级为 https://,这可以正常工作。但我想利用 websocket 协议而不是依赖于 http(s) 轮询。
服务器版本: Apache/2.4.7 (Ubuntu)
相关mod: mod_proxy、mod_proxy_http、mod_proxy_wstunnel、mod_rewrite、mod_ssl
Iptables:我已打开端口 80、443 和 9000。
虚拟主机:
我在 *:443 上创建了一个名为 socket.example.com 的虚拟主机。其预期目的是反向代理 [wss,https]://socket.example.com/ 指向在 http://localhost:9000/ 运行的 socket.io 服务器。就是这样,删除了无关的位:
<VirtualHost *:443>
ServerName socket.example.com
DocumentRoot /var/www/example/socket.io/
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) wss://localhost:9000/$1 [P,L]
## I have also tried the following RewriteRules: ##
# RewriteRule /(.*) http://localhost:9000/$1 [P,L]
# RewriteRule /(.*) http://localhost:9000/socket.io/$1 [P,L]
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/www.example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/keys/0001_key-certbot.pem
SSLCACertificateFile /etc/letsencrypt/ca-bundle.pem
SSLProxyEngine On
ProxyRequests Off
ProxyPreserveHost On
ProxyVia Full
ProxyPass / http://localhost:9000/
ProxyPassReverse / http://localhost:9000/
</VirtualHost>
在我的 websocket 服务器切换到 node.js 之前,我使用上面的 Apache VirtualHost 成功地将 wss://socket.example.com/ws_daemon.php 路由到 ws://localhost:9000/ws_daemon.php 。在这种情况下,我 1. 删除了重写规则,并 2. 将 ProxyPass 设置更改为:
ProxyPass / ws://localhost:9000/
ProxyPassReverse / ws://localhost:9000/
但是相同的逻辑似乎并没有延续到socket.io。
此时我已经没有想法了。任何帮助将不胜感激!
如果您使用
<Location>
块,则应向其中添加以下行:
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
RewriteRule /socket.io/(.*) ws://localhost:3000/socket.io/$1 [P]