WebSocket协议是HTTP协议的扩展。 然而,Apache2的代理模块似乎并不知道,并抛出重要的标题,将呼叫转换为标准的HTTP调用。
有没有办法让Apache2(1)理解WebSocket或(2)只是盲目地传递任何它得到?
Apache中继现在有一个名为mod_proxy_wstunnel的模块,它允许mod_proxy(ProxyPass / ProxyPassReverse)通过WebSocketstream量。 有人写了一篇关于将mod_proxy_wstunnel移植到Apache 2.4 / 2.2的博客文章,并提供了一个补丁。
我find了在Ubuntu上设置mod_proxy_wstunnel的具体指令 (用Ubuntu Server 11.10和Apache 2.2.20testing),并将它们发布到我的博客上。 我已经在下面复制了它们:
# 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
没有什么可以指示 Apache httpd将很快支持他们。
如果你必须通过Apache运行websockets,请尝试mod_pywebsocket 。 我已经尝试过了,它确实有效。
这里有一些我更喜欢的select:
看起来像一个断开连接插件和一些额外的代码的组合现在是可能的:
http://blog.alex.org.uk/2012/02/16/using-apache-websocket-to-proxy-tcp-connection/
请看http://github.com/disconnect/apache-websocket
apache-websocket模块是一个Apache 2.x服务器模块,可用于通过Apache 2.x服务器使用WebSocket协议处理请求。
这添加到@Andrew莫斯的答案如何正确configurationVirtualHost
与socket.io 1.0工作! 随意跳过关于CentOS的部分!
如果你被困在CentOS 6上,下面是如何做到这一点:
mod_proxy_wstunnel
模块的backported源代码(克隆Gist或单独下载文件) yum install make gcc httpd-devel
.c
文件复制到环境的SOURCES
子文件夹中,并将.spec
文件.spec
到SPECS
子文件夹中。 rpmbuild -ba mod_proxy_wstunnel.spec
SRPMS
子文件夹中 rpm -i /path/to/package.rpm
这也将自动加载模块在Apache中,所以你只需要重新启动service httpd restart
。
设置一个VirtualHost
实际上服务于Socket.io服务器和客户端脚本(在http://your.server/socket.io/socket.io.js
默认可用)在Apache 2.2上稍微复杂一点,由于mod_proxy
模块中存在一个Bug :
鉴于以下重写规则:
RewriteRule ^/ws(.*)$ ws://localhost:9000/ws [P]
mod_rewrite
将这个文件path视为访问日志显示:[26/Sep/2013:09:46:07 -0400] "GET /ws://localhost:9000/ws HTTP/1.1" 400 317
所以,你不能在重写规则中使用ws
-protocol ,因为这会在内部变成HTTP GET请求。
尽pipe有一个解决方法:
<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>
这确保发送到/socket.io
所有内容都转到ws://
-protocol,除了长轮询请求(这是WebSocket不可用时的回退机制)和对客户端库的请求之外。