我正在尝试使用 mod_proxy_wstunnel 配置 Apache 2.4,以便将 socket.io 的 websocket 连接代理到 node.js websocket 服务器。使用 socket.io 0.9 时,我们可以很好地完成此操作,但随着 1.0 版本的发布,他们将套接字端点更改为查询参数,现在我无法使用正确的代理指令配置 apache。
所有对 的请求/socket.io/?EIO=N&transport=websocket
(其中 N 是任意数字,通常为 2)都需要转发到ws://localhost:8082/socket.io/
,但所有其他请求都需要转发到http://localhost:8082/socket.io/
。
我尝试过以下两种配置的变体:
ProxyPass /socket.io/?EIO=2&transport=websocket http://localhost:8082/socket.io/?EIO=2&transport=websocket
ProxyPassReverse /socket.io/?EIO=2&transport=websocket http://localhost:8082/socket.io/?EIO=2&transport=websocket
ProxyPass /socket.io/ http://localhost:8082/socket.io/
ProxyPassReverse /socket.io/ http://localhost:8082/socket.io/
。
RewriteRule /socket.io/?EIO=([0-9]+)&transport=websocket ws://localhost:8082/socket.io/ [QSA,P]
ProxyPass /socket.io/ http://localhost:8082/socket.io/
ProxyPassReverse /socket.io/ http://localhost:8082/socket.io/
我从谷歌搜索中得知,ProxyPass 和 Locations 无法定位查询字符串,那么这里还有其他选择吗?路径被硬编码到 socket.io 中,因此除非分叉整个库,否则我无法更改它们。
答案1
使用重写条件来匹配这种特殊情况:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:8082/$1 [P,L]
ProxyPass /socket.io http://localhost:8082/socket.io
ProxyPassReverse /socket.io http://localhost:8082/socket.io
注:正如 Mark W 在下面指出的那样。这些必须在 vhost 级别输入,而不是在服务器或 .htaccess 级别输入。
您还可以参考平衡器:
<Proxy balancer://http-localhost/>
BalancerMember http://localhost:8082 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
BalancerMember http://localhost:8083 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
ProxySet lbmethod=bytraffic
</Proxy>
<Proxy balancer://ws-localhost/>
BalancerMember ws://localhost:8082 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
BalancerMember ws://localhost:8083 keepalive=On smax=1 connectiontimeout=10 retry=600 timeout=900 ttl=900
ProxySet lbmethod=bytraffic
</Proxy>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) balancer://ws-localhost/$1 [P,L]
ProxyPass /socket.io balancer://http-localhost/socket.io
ProxyPassReverse /socket.io balancer://http-localhost/socket.io