为 Socket.IO 1.0 配置 Apache 2.4 mod_proxy_wstunnel

Chi*_*oft 17 reverse-proxy socket node.js apache-2.4

我正在尝试配置 Apache 2.4 以使用 mod_proxy_wstunnel 将 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/
Run Code Online (Sandbox Code Playgroud)

.

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/
Run Code Online (Sandbox Code Playgroud)

我从谷歌搜索中了解到 ProxyPass 和 Locations 无法定位查询字符串,那么这里还有其他选择吗?路径被硬编码到 socket.io 中,所以如果没有分叉整个库,我无法更改它们。

小智 40

使用重写条件来匹配这种特殊情况:

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
Run Code Online (Sandbox Code Playgroud)

注意如下面的 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
Run Code Online (Sandbox Code Playgroud)

  • **注意**:这些块应该按照所描述的确切顺序放置在`&lt;VirtualHost&gt;` 块中,*即使您使用的是文档根目录*(例如`/var/www/html`)。我花了将近 2 个小时试图弄清楚为什么这些更改无法正常工作,结果发现 `RewriteRule` 在 `httpd.conf` 的根级别没有工作(尽管 `ProxyPass` 工作正常)。`ProxyPass` 指令在 `&lt;Directory&gt;` 块或 `.htaccess` 文件中不起作用(尽管 `RewriteRule` 可以),因此对这些更改进行分组的逻辑位置是在 `&lt;VirtualHost&gt;` 中。 (5认同)