为Socket.IO 1.0配置Apache 2.4 mod_proxy_wstunnel


15

我正在尝试配置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/

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中,因此如果没有分叉整个库,我就无法更改它们。

Answers:


39

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

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所述。这些必须在虚拟主机级别而不是服务器或.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

+100000你成就了我的一天。在这里待了几个小时。我使用了第一个代码段。我目前不需要平衡器。
Eamorr 2014年

我无法使它正常工作。Apache始终以404代码进行响应。它显示在访问日志中,好像正在尝试加载普通文件一样,并且套接字节点进程未显示接收请求的迹象(它确实显示了对socket.io.js文件的调用)
ChiperSoft

1
看来mod_rewrite不知道ws://协议。我在重写日志中看到了这一点:forcing proxy-throughput with http://[REDACTED].dev/ws://localhost:8082/socket.io/(domain.dev
ChiperSoft

可能是以下原因:issue.apache.org/bugzilla/show_bug.cgi?id=55598好像在Apache 2.5中添加了对该协议的支持
ChiperSoft

5
注意即使您使用文档根目录(例如)<VirtualHost>应按照所述的确切顺序将这些块放置在块中/var/www/html。我花了将近2个小时的时间来弄清楚为什么这些更改无法正常工作,只是为了发现RewriteRules的功能在httpd.conf(虽然ProxyPass在起作用)的根本水平上没有起作用。该ProxyPass指令不要在工作<Directory>块或.htaccess文件(尽管RewriteRule我们做),这样的逻辑的地方,一群这些变化是<VirtualHost>
Mark W
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.