Настройка Apache 2.4 mod_proxy_wstunnel для Socket.IO 1.0

15

Я пытаюсь настроить Apache 2.4 для прокси соединения websocket для socket.io с сервером node.js websocket, используя mod_proxy_wstunnel. У нас это работало нормально с 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, поэтому если не разветвлять всю библиотеку, я не могу их изменить.

ChiperSoft
источник

Ответы:

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

ПРИМЕЧАНИЕ Как отмечено 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
PeterPramb
источник
+100000 Ты сделал мой день. Занимался этим часами. Я использовал первый фрагмент кода. Мне не нужен балансировщик в данный момент.
Eamorr
Я не могу заставить это работать. 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
Вероятно, поэтому: questions.apache.org/bugzilla/show_bug.cgi?id=55598 Похоже, что поддержка протокола была добавлена ​​в Apache 2.5
ChiperSoft
5
ПРИМЕЧАНИЕ . Эти блоки следует размещать внутри <VirtualHost>блока в точном порядке, даже если вы используете корневой каталог документа (например /var/www/html). Я потратил почти 2 часа, пытаясь выяснить, почему эти изменения не работали должным образом, только чтобы выяснить, что RewriteRuleони не функционируют на корневом уровне httpd.conf(хотя ProxyPassи работают). Эти ProxyPassдирективы не работают в <Directory>блоках или .htaccessфайлах (хотя RewriteRule«s делать), так что логическое место в группе эти изменения в <VirtualHost>.
Марк W