O protocolo WebSocket é uma extensão do protocolo HTTP. No entanto, o módulo proxy do Apache2 parece desconhecer e joga fora cabeçalhos cruciais, convertendo a chamada em uma chamada HTTP padrão.
Existe uma maneira de fazer o Apache2 (1) entender o WebSocket ou (2) simplesmente transmitir cegamente o que obtém?
Agora existe um módulo no tronco do Apache chamado mod_proxy_wstunnel que permite que o mod_proxy (ProxyPass / ProxyPassReverse) passe pelo tráfego do WebSocket. Alguém escreveu um post de blog sobre a portabilidade de mod_proxy_wstunnel para o Apache 2.4 / 2.2 e forneceu um patch para isso.
# Check apache version (should be 2.2.20 as of writing, if not adjust the next step)
dpkg -s apache2
# Checkout apache source
svn checkout http://svn.apache.org/repos/asf/httpd/httpd/tags/2.2.20/ httpd-2.2.20
# Get patch and apply it
wget http://cafarelli.fr/gentoo/apache-2.2.24-wstunnel.patch
cd httpd-2.2.20
patch -p1 < ../apache-2.2.24-wstunnel.patch
# Build Apache
svn co http://svn.apache.org/repos/asf/apr/apr/branches/1.4.x srclib/apr
svn co http://svn.apache.org/repos/asf/apr/apr-util/branches/1.3.x srclib/apr-util
./buildconf
./configure --enable-proxy=shared --enable-proxy_wstunnel=shared
make
# Copy the module and recompiled mod_proxy (for new symbols) to the ubuntu apache installation and update the permissions to match the other modules
sudo cp modules/proxy/.libs/mod_proxy{_wstunnel,}.so /usr/lib/apache2/modules/
sudo chmod 644 /usr/lib/apache2/modules/mod_proxy{_wstunnel,}.so
echo -e "# Depends: proxy\nLoadModule proxy_wstunnel_module /usr/lib/apache2/modules/mod_proxy_wstunnel.so" | sudo tee -a /etc/apache2/mods-available/proxy_wstunnel.load
# Enable the module (also make any configuration changes you need)
sudo a2enmod proxy_wstunnel
sudo service apache2 restart
Quando segui o seu guia, houve um passo que você não deu. Depois de fazer os checkouts de abril, tive que executar ./buildconfigpara criar o arquivo de configuração. E havia algumas dependências que ele me disse para instalar.
Apenas o meu feedback ... este instalado e carregado no apache 2.2.22-1ubuntu1.10 do Ubuntu 12.04, mas não funcionou para mim no final. O proxy estava removendo o cabeçalho "Upgrade" (o código fonte diz "RFC2616 13.5.1 diz que devemos remover esses cabeçalhos"), que é um cabeçalho que o servidor espera, não apenas um salto, por isso não funcionou para mim, e substituí-o por uma regra DNAT do iptables.
O módulo apache-websocket é um módulo do servidor Apache 2.x que pode ser usado para processar solicitações usando o protocolo WebSocket por um servidor Apache 2.x.
Eu olhei para o projeto github acima. Não atua como proxy. citaçãoThe module consists of a plugin architecture ...
guettli
1
Isso adiciona à resposta de @Andrew Moss 'sobre como configurar corretamente o VirtualHostpara trabalhar com o socket.io 1.0! Sinta-se livre para pular a parte sobre o CentOS!
Se você está preso no CentOS 6, veja como fazê-lo:
Faça o download da fonte de backport para o mod_proxy_wstunnelmódulo aqui (clone o Gist ou faça o download dos arquivos individualmente)
Instale tudo o necessário para construir: yum install make gcc httpd-devel
Configurar um ambiente RPM Build (basicamente um usuário sem privilégios e alguns diretórios)
Copie o .carquivo-na SOURCESsubpasta do ambiente e o .specarquivo-na SPECSsubpasta.
Corre rpmbuild -ba mod_proxy_wstunnel.spec
O pacote está agora na SRPMSsubpasta
Instale o pacote: rpm -i /path/to/package.rpm
Lucro
Isso também carregará automaticamente o módulo no Apache, então você só precisa reiniciá-lo service httpd restart.
A configuração de um VirtualHostpara realmente servir o servidor Socket.io e o script do cliente (disponível por padrão em http://your.server/socket.io/socket.io.js) é um pouco mais complicado no Apache 2.2, devido a um erro no mod_proxymódulo :
Dada a seguinte regra de reescrita:
RewriteRule ^/ws(.*)$ ws://localhost:9000/ws [P]
mod_rewrite trata esse caminho de arquivo para que o log de acesso mostre:
Portanto, você não pode usar o wsprotocolo-em uma regra de reescrita , porque isso se transformará internamente em uma solicitação HTTP GET.
Existe uma solução alternativa:
<VirtualHost *:80>
ServerName your.server
# Proxy socket.io Websocket
RewriteEngine On
# socket.io 1.0+ starts all connections with an HTTP polling request
RewriteCond %{QUERY_STRING} transport=polling [NC]
RewriteRule /(.*) http://localhost:8081/$1 [P]
ProxyRequests Off
# Explicitly send the request for the client-script to HTTP:
ProxyPass /socket.io/socket.io.js http://localhost:8081/socket.io/socket.io.js
ProxyPassReverse /socket.io/socket.io.js http://localhost:8081/socket.io/socket.io.js
# Anything else goes to the WebSocket protocol:
ProxyPass /socket.io/ ws://localhost:8081/socket.io/
ProxyPassReverse /socket.io/ ws://localhost:8081/socket.io/
# Any additional stuff (the actual site) comes here
ProxyPass / http://localhost:8081/
ProxyPassReverse / http://localhost:8081/
</VirtualHost>
Isso garante que tudo enviado para /socket.iová para o ws://protocolo-, exceto a solicitação de pesquisa longa (que é um mecanismo de fallback quando o WebSockets não está disponível) e a solicitação da biblioteca-cliente.
./buildconfig
para criar o arquivo de configuração. E havia algumas dependências que ele me disse para instalar.Não há nada para indicar que o Apache httpd os apoiará em breve.
Se você deve executar websockets através do apache, tente mod_pywebsocket . Eu tentei e funciona.
Aqui estão algumas alternativas que eu prefiro:
fonte
Parece que, com uma combinação do plug-in de desconexão e algum código extra, isso agora é possível:
http://blog.alex.org.uk/2012/02/16/using-apache-websocket-to-proxy-tcp-connection/
fonte
Por favor, dê uma olhada em http://github.com/disconnect/apache-websocket
fonte
The module consists of a plugin architecture ...
Isso adiciona à resposta de @Andrew Moss 'sobre como configurar corretamente o
VirtualHost
para trabalhar com o socket.io 1.0! Sinta-se livre para pular a parte sobre o CentOS!Se você está preso no CentOS 6, veja como fazê-lo:
mod_proxy_wstunnel
módulo aqui (clone o Gist ou faça o download dos arquivos individualmente)yum install make gcc httpd-devel
.c
arquivo-naSOURCES
subpasta do ambiente e o.spec
arquivo-naSPECS
subpasta.rpmbuild -ba mod_proxy_wstunnel.spec
SRPMS
subpastarpm -i /path/to/package.rpm
Isso também carregará automaticamente o módulo no Apache, então você só precisa reiniciá-lo
service httpd restart
.A configuração de um
VirtualHost
para realmente servir o servidor Socket.io e o script do cliente (disponível por padrão emhttp://your.server/socket.io/socket.io.js
) é um pouco mais complicado no Apache 2.2, devido a um erro nomod_proxy
módulo :Portanto, você não pode usar o
ws
protocolo-em uma regra de reescrita , porque isso se transformará internamente em uma solicitação HTTP GET.Existe uma solução alternativa:
Isso garante que tudo enviado para
/socket.io
vá para ows://
protocolo-, exceto a solicitação de pesquisa longa (que é um mecanismo de fallback quando o WebSockets não está disponível) e a solicitação da biblioteca-cliente.fonte